【问题标题】:Unique Items in a pandas dataframe with a list带有列表的熊猫数据框中的唯一项目
【发布时间】:2018-05-19 04:59:36
【问题描述】:

我正在尝试从 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 个列,因此我无法显式输入这些列。

提前非常感谢!

【问题讨论】:

  • 也许这里是使用套装的好地方? set([1,2]) == set([2,1]) 是真的
  • 旁注,如果您不必按顺序删除列,您可以只形成一个范围内列的列表,然后在for 循环之后将它们一起删除。

标签: python pandas dataframe


【解决方案1】:

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',)]

【讨论】:

    【解决方案2】:

    一种方法是将麻烦的类型转换为可散列的替代方案。在下面的示例中,有 14 个元素,但是在将两边都转换为 frozenset 之后,[1, 2] == [2, 1] 和另外,0 == False。所以我们计算出 12 个唯一值。

    s = pd.Series([[1, 2], [2, 1], (1, 2, 3), {5, 1}, 3142, 563.123, np.nan, 'dfa',
                   '', 'dsafa', 3214, 0, True, False])
    
    print(len(s))  # 14
    
    def converter(x):
        return frozenset(x) if isinstance(x, (set, list)) else x
    
    print(len(s.apply(converter).unique()))  # 12
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-16
      • 2020-06-15
      • 2018-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多