首页 > 解决方案 > 带有列表的熊猫数据框中的唯一项目

问题描述

我正在尝试从 pandas 数据框中删除所有列,其中列中的唯一项少于 10 个。但是,我的一些数据是列表,我得到了错误unhashable type: 'list'。有道理,因为 pandas 与 hashmap 进行比较。

我目前的代码是

for i in df.columns:
    if len(df[i].unique()) < 10:
        df.drop(i, 1)

在我到达一个列表对象之前,它工作得很好。出于我的目的, list1 和 list2 不是唯一的。[1, 2]并且[2, 1]不是唯一的,即使[1, 2] == [2, 1]是 False。

我应该如何执行此操作?将列表分开是没有意义的,因为我有 1400 个列,所以我不能明确地输入这些列。

提前谢谢了!

标签: pythonpandasdataframe

解决方案


list对象不可散列,因为它们是可变的,但tuple另一方面,它们是不可变的。您可以transform列出tuple并使用此属性的值。

假设你有

df = pd.DataFrame({"A": [1,2,3,4], 
                   "B": ["a", "b", "c", "d"],
                   "C": [[1,2,3], [2], [2,3,1], [4]] })

    A   B   C
0   1   a   [1, 2, 3]
1   2   b   [2]
2   3   c   [2, 3, 1]
3   4   d   [4]

因此,您可以执行类似的操作

df.C.apply(sorted).transform(tuple).unique()

返回

array([(1, 2, 3), (2,), (4,)], dtype=object)

因此,您的代码可能如下所示,collections.Hashable用于检查列的内容是否确实是可散列的

import collections

for i in df.columns:
    if isinstance(df[i].iloc[0], collections.Hashable):
        if len(df[i].unique()) < 10: 
            df = df.drop(i, 1)
    else:
        if len(df[i].apply(sorted).transform(tuple).unique()) < 10: 
            df = df.drop(i, 1)

请注意,这也适用于其他不可散列的类型,例如dicts

>>> df["D"] = [{"a":2}, {}, {"k":3}, {"k":3}]})
>>> print(df.D.apply(sorted).transform(tuple).unique())
[('a',) () ('k',)]

推荐阅读