首页 > 解决方案 > 了解为什么 drop.duplicates() 不起作用

问题描述

假设我有一个 2 行 pandas 数据帧,它是通过子集更大的数据帧获得的。

             TransID     rev    offer         qs   lt         chan  
212    RTSO118981094  737.24  ABCXCS           3  d382        O78   
53311  RTSO118981094  737.24  ABCXCS           3  d382        O78   

rev 是一个浮点数,已四舍五入到小数点后 2 位。

两行看起来相同,当我做“差异”时没有输出。即使是这样,

df = df.drop_duplicates() 

没有效果。它们的字段长度都相同。

如何让它工作?

标签: pythonpandas

解决方案


那么在这种情况下,问题是您拥有的混合类型。调查数据的一种常用方法是将其导出,例如to_dict()

df.to_dict()

还要考虑这个例子:

import pandas as pd

df1 = pd.DataFrame({
    'a': [3,3],
    'b': ["d382","d382"]
})

df2 = pd.DataFrame({
    'a': ['3',3],
    'b': ["d382","d382"]
})

df3 = pd.DataFrame({
    'a': ['3','3'],
    'b': ["d382","d382"]
})

print(df1.dtypes) # <-- Use dtypes to reveal what data types your columns hold
print(df2.dtypes) # <-- Use dtypes to reveal what data types your columns hold
print(df3.dtypes) # <-- Use dtypes to reveal what data types your columns hold

回报:

df1               df2               df3
a     int64       a    object       a    object
b    object       b    object       b    object
dtype: object     dtype: object     dtype: object  

进一步探索:在 pandas 中,对象类型可以包含不同的类型。这可能会产生一个棘手的情况,我们混合整数、列表、类......你说的。

现在让我们只选择那些列并使用它applymap(type)来找出每个单元格中的类型。看看上面的例子,错误的数据框是 df2,它在列中包含a不同类型的对象。

print(df1.select_dtypes(include=['object']).applymap(type))
print(df2.select_dtypes(include=['object']).applymap(type))
print(df3.select_dtypes(include=['object']).applymap(type))

               b
0  <class 'str'>
1  <class 'str'>
               a              b
0  <class 'str'>  <class 'str'>       # <--- look at column a
1  <class 'int'>  <class 'str'>       # <--- it has mixed types
               a              b
0  <class 'str'>  <class 'str'>
1  <class 'str'>  <class 'str'>

最后,让我们现在创建一个遍历所有对象列的函数并检查一切是否正确。这是由每列中值集的长度定义的。在“正确”列中,所有元素都应属于同一类型:

def check_obj_columns(dfx):
    tdf = dfx.select_dtypes(include=['object']).applymap(type)
    for col in tdf:
        if len(set(tdf[col].values)) > 1:
            print("Column {} has mixed object types.".format(col))

check_obj_columns(df1) # Returns nothing
check_obj_columns(df2) # Returns: Column a has mixed object types.
check_obj_columns(df3) # Returns nothing

这意味着 df2 具有a混合类型的对象列。


在你的情况下:

TransID     object
rev        float64
offer       object
qs          object   # <-- this element here is an object if you got mixed types
lt          object
chan        object
dtype: object

推荐阅读