【问题标题】:Python Pandas : Drop Duplicates Function - Unusual BehaviourPython Pandas:删除重复函数 - 异常行为
【发布时间】:2022-01-15 05:56:40
【问题描述】:

错误 -> TypeError: unhashable type: 'list' disappears 在保存数据框并再次加载后...

两个数据帧 [保存和加载、生成] 具有相同的 dtypes ...

可重现->

--> import pandas as pd
--> l1 = [[1], [1], [1], [1], [1], [1], [1], [1], [6], [1], [6], [1], [6], [6], [6], [6], [6], [6], [6], [6], [6]]

## len(l1) is 21 ##

--> l2 = ['a']*21
--> l3 = ['c']*10 + ['d']*10 + ['e']
--> df = pd.DataFrame()
--> df['col1'], df['col2'], df['col3'] = l1, l3, l2
--> df
        col1 col2 col3
        0   [1]    c    a
        1   [1]    c    a
        2   [1]    c    a
        3   [1]    c    a
        4   [1]    c    a
        5   [1]    c    a
        6   [1]    c    a
        7   [1]    c    a
        8   [6]    c    a
        9   [1]    c    a
        10  [6]    d    a
        11  [1]    d    a
        12  [6]    d    a
        13  [6]    d    a
        14  [6]    d    a
        15  [6]    d    a
        16  [6]    d    a
        17  [6]    d    a
        18  [6]    d    a
        19  [6]    d    a
        20  [6]    e    a

--> df.dtypes
        col1    object
        col2    object
        col3    object
        dtype: object

--> df.drop_duplicates(subset=['col1', 'col2', 'col3'], keep='last', inplace=True)
        
        ## TypeError: unhashable type: 'list' ##

## Here if I save it as an excel and load again, then this error does not come up ... ##

--> df.to_excel('test.xlsx')
--> df_ = pd.read_excel('test.xlsx')
--> df_.dtypes
        Unnamed: 0     int64
        col1    object
        col2    object
        col3    object
        dtype: object
--> df_.drop_duplicates(subset=['col1', 'col2', 'col3'], keep='last', inplace=True)
--> df_
         Unnamed: 0 col1 col2 col3
        8       8   [6]    c    a
        9       9   [1]    c    a
        11      11  [1]    d    a
        19      19  [6]    d    a
        20      20  [6]    e    a

这种行为有解释吗?

问题的扩展追溯

Traceback(最近一次调用最后一次):

文件“”,第 1 行,在

文件“C:\Users\Agnij\Anaconda3\lib\site-packages\pandas\core\frame.py”,第 4811 行,在 drop_duplicates 中

duplicated = self.duplicated(subset, keep=keep)

文件“C:\Users\Agnij\Anaconda3\lib\site-packages\pandas\core\frame.py”,第 4888 行,一式两份 标签,形状 = map(list, zip(*map(f, vals)))

文件“C:\Users\Agnij\Anaconda3\lib\site-packages\pandas\core\frame.py”,第 4863 行,在 f vals, size_hint=min(len(self), _SIZE_HINT_LIMIT)

文件“C:\Users\Agnij\Anaconda3\lib\site-packages\pandas\core\algorithms.py”,第 636 行,分解值,na_sentinel=na_sentinel,size_hint=size_hint,na_value=na_value

文件“C:\Users\Agnij\Anaconda3\lib\site-packages\pandas\core\algorithms.py”,第 484 行,在 _factorize_array 唯一性中,代码 = table.factorize(values, na_sentinel=na_sentinel, na_value= na_value)

文件“pandas_libs\hashtable_class_helper.pxi”,第 1815 行,在 pandas._libs.hashtable.PyObjectHashTable.factorize 中

文件“pandas_libs\hashtable_class_helper.pxi”,第 1731 行,在 pandas._libs.hashtable.PyObjectHashTable._unique 中

【问题讨论】:

    标签: python pandas list dataframe drop-duplicates


    【解决方案1】:

    drop_duplicates 对对象进行哈希处理,以高效地跟踪哪些对象已被查看。

    lists 不可散列(因为它们是可变的),因此您不能直接对它们使用 drop_duplicates。当您保存和加载数据时,可能会将其转换为字符串,从而可以计算哈希。

    要解决这个问题,您可以将列表转换为可散列的元组:

    df['col1'] = df['col1'].apply(tuple)
    # now this runs with no error
    df.drop_duplicates(subset=['col1', 'col2', 'col3'], keep='last', inplace=True)
    

    【讨论】:

    • 谢谢!正如@enke 所指出的,我直接将其转换为 str -> df['col1'] = df['col1'].astype(str),如果遇到具有多个值的列表,将考虑元组方式。跨度>
    • @Agnij 是的,当然,这也有效。问题只是如果您需要再次拥有列表,则可能更难以撤消操作。顺便说一句,如果你有单个元素,为什么要使用列表呢?直接把元素存到列里不就行了?
    • 目前没有将其反转...但如果需要,我会参考这个。想到了这一点,但只是想在出现多个元素的情况下更安全......这是一个元素数量的范围没有完全定义的情况
    【解决方案2】:

    因为即使两列都是 dtype 对象,它们中的项目也是不同的类型:

    >>> df.loc[0,'col1']
    [1]
    
    
    >>> df_.loc[0, 'col1']
    '[1]'
    

    由于字符串是可散列的,因此您看不到以前使用列表时遇到的错误。

    【讨论】:

    • 明白谢谢!,只是在看 dtype 对象
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 2014-10-23
    • 2013-02-05
    • 2018-12-13
    • 2014-03-08
    相关资源
    最近更新 更多