【问题标题】:Pandas drop duplicates on elements made of listsPandas 在由列表组成的元素上放置重复项
【发布时间】:2018-10-29 07:08:37
【问题描述】:

假设我的数据框是:

df = pandas.DataFrame([[[1,0]],[[0,0]],[[1,0]]])

产生:

        0
0  [1, 0]
1  [0, 0]
2  [1, 0]

如果我写的话,我想删除重复项,并且只获取元素 [1,0] 和 [0,0]:

df.drop_duplicates()

我收到以下错误:TypeError: unhashable type: 'list'

如何调用 drop_duplicates()?

更笼统地说:

df = pandas.DataFrame([[[1,0],"a"],[[0,0],"b"],[[1,0],"c"]], columns=["list", "letter"])

我想调用 df["list"].drop_duplicates(),所以 drop_duplicates 适用于系列而不是数据框?

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    你可以使用numpy.unique()函数:

    >>> df = pandas.DataFrame([[[1,0]],[[0,0]],[[1,0]]])
    >>> pandas.DataFrame(np.unique(df), columns=df.columns)
            0
    0  [0, 0]
    1  [1, 0]
    

    如果您想保留订单结帐:numpy.unique with order preserved

    【讨论】:

    • 我喜欢这个答案,很简单
    • @user 如果您认为一个答案比其他答案更好,最好“接受”它,以便其他人知道哪种解决方案最有效。
    • @Omid 所有答案都很棒,而且都被赞成,但这是我为了简单而使用的答案
    • 看起来像这样或者应该将元组答案添加到熊猫代码库中。
    【解决方案2】:

    drop_duplicates

    在元组数据上调用drop_duplicates

    df[0].apply(tuple, 1).drop_duplicates().apply(list).to_frame()
    
            0
    0  [1, 0]
    1  [0, 0]
    

    collections.OrderedDict

    不过,我更喜欢不涉及apply...

    from collections import OrderedDict
    pd.Series(map(
        list, (OrderedDict.fromkeys(map(tuple, df[0].tolist()))))
    ).to_frame()
    

    或者,

    pd.Series(
        list(k) for k in OrderedDict.fromkeys(map(tuple, df[0].tolist()))
    ).to_frame()
    

            0
    0  [1, 0]
    1  [0, 0]
    

    【讨论】:

    • 你为什么更喜欢不涉及应用的东西?使用 apply 后代码看起来更具可读性。
    • @wordsforthewise 这个问题的答案很长,但在这里:stackoverflow.com/questions/54432583/…
    【解决方案3】:

    这是一种方法,将您的一系列列表转换为单独的列,并且只保留非重复项:

    df[~df[0].apply(pandas.Series).duplicated()]
    
            0
    0  [1, 0]
    1  [0, 0]
    

    说明:

    df[0].apply(pandas.Series) 返回:

       0  1
    0  1  0
    1  0  0
    2  1  0
    

    您可以从中找到重复项:

    >>> df[0].apply(pd.Series).duplicated()
    0    False
    1    False
    2     True
    

    最后使用那个索引

    【讨论】:

      【解决方案4】:

      我尝试了其他答案,但没有解决我需要的问题(具有多个列表列的大型数据框)。

      我是这样解决的:

      df = df[~df.astype(str).duplicated()]
      

      【讨论】:

        猜你喜欢
        • 2021-08-12
        • 2018-09-20
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        • 2015-05-11
        • 2021-05-24
        • 2018-11-03
        • 2015-12-13
        相关资源
        最近更新 更多