Python Pandas : 删除重复函数 - 异常行为
Python Pandas : Drop Duplicates Function - Unusual Behaviour
错误 -> TypeError: unhashable type: 'list' disappears after saving the data frame and loading it again ...
两个数据框[已保存和加载,已生成]具有相同的数据类型 ...
可重现 ->
--> 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
这种行为有解释吗?
问题的扩展追溯
回溯(最近调用最后):
中的文件“”,第 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 行,重复
标签,shape = 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 uniques 中,代码 = table.factorize(值,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
中
drop_duplicates
对对象进行哈希处理以有效地跟踪哪些已被看到或未被看到。
list
不可散列(因为它们是可变的),因此您不能直接对它们使用 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)
因为即使两列都是 dtype 对象,它们中的项目也是不同的类型:
>>> df.loc[0,'col1']
[1]
>>> df_.loc[0, 'col1']
'[1]'
由于字符串是可哈希的,因此您不会看到之前使用列表时遇到的错误。
错误 -> TypeError: unhashable type: 'list' disappears after saving the data frame and loading it again ...
两个数据框[已保存和加载,已生成]具有相同的数据类型 ...
可重现 ->
--> 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
这种行为有解释吗?
问题的扩展追溯
回溯(最近调用最后):
中的文件“”,第 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 行,重复 标签,shape = 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 uniques 中,代码 = table.factorize(值,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
中drop_duplicates
对对象进行哈希处理以有效地跟踪哪些已被看到或未被看到。
list
不可散列(因为它们是可变的),因此您不能直接对它们使用 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)
因为即使两列都是 dtype 对象,它们中的项目也是不同的类型:
>>> df.loc[0,'col1']
[1]
>>> df_.loc[0, 'col1']
'[1]'
由于字符串是可哈希的,因此您不会看到之前使用列表时遇到的错误。