使用熊猫从csv删除重复项时出现错误

时间:2018-11-21 09:18:06

标签: python pandas csv

我的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

请指出我做错了什么? 谢谢

1 个答案:

答案 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)))