получить ошибку при удалении дубликатов из CSV с помощью панд - PullRequest
0 голосов
/ 21 ноября 2018

Мой CSV-файл находится по этой ссылке:

https://drive.google.com/file/d/1Pac9-YLAtc7iaN0qEuiBOpYYf9ZPDDaL/view?usp=sharing

Я хочу удалить дубликат из CSV, проверив длину жанров против каждого ID художника.Если у исполнителя есть 2 записи в формате csv (например, идентификатор ed sheeran 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 голосов
/ 21 ноября 2018

В строке 16553 входного csv-файла у вас есть неверные данные:

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: [])

Или, что более элегантно, переключиться на чтение csv с помощью na_filter=False:

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)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...