我的csv文件在此链接上:
https://drive.google.com/file/d/1Pac9-YLAtc7iaN0qEuiBOpYYf9ZPDDaL/view?usp=sharing
我想通过针对每个演出者ID检查流派的长度,从csv中删除重复项。如果某位艺术家在csv中有2条记录(例如ed sheeran的id 6eUKZXaKkcviH0Ku9w2n3V 有2条记录,则一条记录具有1种流派,而第5行则具有5种流派,所以我想保留具有最大流派长度的行)
我现在正在使用此脚本:
import pandas
import ast
df = pandas.read_csv('39K.csv', encoding='latin-1')
df['lst_len'] = df['genres'].map(lambda x: len(ast.literal_eval(str(x))))
print(df['lst_len'][0])
df = df.sort_values('lst_len', ascending=False)
# Drop duplicates, preserving first (longest) list by ID
df = df.drop_duplicates(subset='ID')
# Remove extra column that we introduced, write to file
df = df.drop('lst_len', axis=1)
df.to_csv('clean_39K.csv', index=False)
但是此脚本可处理500条记录(可能我错觉记录的大小很重要)
但是当我为最大的文件 39K.csv 运行此脚本时,出现此错误:
Traceback (most recent call last):
******* error in line 5, in <module>....
df['lst_len'] = df['genres'].map(lambda x: len(list(x)))
df['lst_len'] = df['genres'].map(lambda x: len(list(x)))
TypeError: 'float' object is not iterable
请指出我做错了什么? 谢谢
答案 0 :(得分:2)
您输入的csv文件的(至少)行16553处有错误数据:
52lUXCmpmAIVsgNd1uADOy,Moosh & Twist,NULL
pandas
在读取NULL
类型且不可迭代的文件时将nan
解释为float
。那里也有其他一些NULL
条目,因此您可以手动删除或修复它们(首选),或者在代码中处理这种情况。
例如,如果您实际上要假装NULL
应该被解释为空列表,则可以像这样预处理数据(仅在读取csv之后):
df.loc[df['genres'].isnull(),['genres']] = df.loc[df['genres'].isnull(),'genres'].apply(lambda x: [])
或更优雅的是,切换为使用na_filter=False
来读取csv:
df = pandas.read_csv('39K.csv', encoding='latin-1', na_filter=False)
这将防止熊猫首先将这些值替换为nan
。
最后,该代码无法完全满足我们的要求,因为它正在计算列表的字符串表示形式中的字符数。解决方案是将NULL值预处理为代表空列表的字符串,然后使用ast.literal_eval
将所有字符串都转换回列表:
import pandas
import ast
df = pandas.read_csv('39K.csv', encoding='latin-1', na_filter=False)
df.replace(to_replace="NULL", value="[]", inplace=True)
for item in df['genres']:
print(str(item))
print(ast.literal_eval(item))
df['lst_len'] = df['genres'].map(lambda x: len(ast.literal_eval(x)))