Pandas drop_duplicates 方法不适用于包含列表的数据框

Posted

技术标签:

【中文标题】Pandas drop_duplicates 方法不适用于包含列表的数据框【英文标题】:Pandas drop_duplicates method not working on dataframe containing lists 【发布时间】:2017-10-06 22:01:04 【问题描述】:

我正在尝试在我的数据帧上使用 drop_duplicates 方法,但我得到了一个 错误。请参阅以下内容:

错误:TypeError:不可散列的类型:'list'

我正在使用的代码:

df = db.drop_duplicates()

我的数据库很大,包含字符串、浮点数、日期、NaN、布尔值、整数...感谢任何帮助。

【问题讨论】:

显然,它包含导致错误的 lists。一般来说,我认为列表的 DataFrame 是代码气味...... 我知道这是不久前的事了,但请详细说明为什么包含列表的 df 是代码异味? 【参考方案1】:

drop_duplicates 不适用于数据框中的列表,正如错误消息所暗示的那样。但是,您可以在转换为 str 的数据帧上删除重复项,然后使用结果中的索引从原始 df 中提取行。

设置

df = pd.DataFrame('Keyword': 0: 'apply', 1: 'apply', 2: 'apply', 3: 'terms', 4: 'terms',
 'X': 0: [1, 2], 1: [1, 2], 2: 'xy', 3: 'xx', 4: 'yy',
 'Y': 0: 'yy', 1: 'yy', 2: 'yx', 3: 'ix', 4: 'xi')

#Drop directly causes the same error
df.drop_duplicates()
Traceback (most recent call last):
...
TypeError: unhashable type: 'list'

解决方案

#convert hte df to str type, drop duplicates and then select the rows from original df.

df.loc[df.astype(str).drop_duplicates().index]
Out[205]: 
  Keyword       X   Y
0   apply  [1, 2]  yy
2   apply      xy  yx
3   terms      xx  ix
4   terms      yy  xi

#the list elements are still list in the final results.
df.loc[df.astype(str).drop_duplicates().index].loc[0,'X']
Out[207]: [1, 2]

编辑:将 iloc 替换为 loc。在这种特殊情况下,两者都作为 index 匹配位置索引,但不通用

【讨论】:

@Allen 如何在 *** 中添加 Ipython 代码块?我在整个互联网上搜索这种方法,但找不到好的解决方案。 此答案不考虑不同行中同一列中的两个列表包含相同元素但顺序不同的情况。我想这还取决于用户是否希望将具有相同元素但顺序不同的列表视为重复项。【参考方案2】:

@Allen 的回答很好,但有一点问题。

df.iloc[df.astype(str).drop_duplicates().index]

在示例中应该是 loc 而不是 iloc.loot。

a = pd.DataFrame([['a',18],['b',11],['a',18]],index=[4,6,8])
Out[52]: 
   0   1
4  a  18
6  b  11
8  a  18

a.iloc[a.astype(str).drop_duplicates().index]
Out[53]:
...
IndexError: positional indexers are out-of-bounds

a.loc[a.astype(str).drop_duplicates().index]
Out[54]: 
   0   1
4  a  18
6  b  11

【讨论】:

【参考方案3】:

概述:您可以查看哪些行重复

方法一:

df2=df.copy()
mylist=df2.iloc[0,1]
df2.iloc[0,1]=' '.join(map(str,mylist))

mylist=df2.iloc[1,1]
df2.iloc[1,1]=' '.join(map(str,mylist))

duplicates=df2.duplicated(keep=False)
print(df2[duplicates])

方法二:

print(df.astype(str).duplicated(keep=False))

【讨论】:

【参考方案4】:

我还想提一下(以防其他人和我一样愚蠢),如果您错误地将列表列表作为 drop_duplicates 函数的“子集”参数给出,您将得到相同的错误。

结果我花了几个小时寻找一个不在我的数据框中的列表,因为我在参数中放置了一对多括号。

【讨论】:

以上是关于Pandas drop_duplicates 方法不适用于包含列表的数据框的主要内容,如果未能解决你的问题,请参考以下文章

Pandas drop_duplicates - TypeError:*后的类型对象参数必须是序列,而不是映射

等效于 pandas.DataFrame.set_index / drop_duplicates 与 dropDuplicates 的 Spark DataFrame

pandas.DataFrame.drop_duplicates

pandas去重

Pandas常用的数据清洗方法

Pandas数据清洗方法