Есть ли более быстрый способ отделить дубликаты и разные данные от CSV с помощью Python? - PullRequest
0 голосов
/ 04 июля 2018

У меня есть фрейм данных, содержащий миллионы данных. Предположим, что это кадр данных с именем mydataframe:

filename | #insert-1 | #insert-2 | #delete-1 | #delete-2
---------------------------------------------------------
A        |         4 |         4 |         3 |         3
B        |         3 |         5 |         2 |         2
C        |         5 |         5 |         6 |         7
D        |         2 |         2 |         3 |         3
E        |         4 |         5 |         5 |         3
---------------------------------------------------------

Мне нужно отделить файл на основе различного количества вставок или удалений, а затем сохранить их в новый файл CSV с именем different.csv. А также сохраните остальные данные с одинаковым номером вставки и удаления в отдельном файле CSV с именем same.csv. Другими словами, если файл имеет другое число между #insert-1 и #insert-2 или #delete-1 и #delete-2, сохраните его в different.csv, в противном случае сохраните в same.csv.

Ожидаемый результат: different.csv

filename | #insert-1 | #insert-2 | #delete-1 | #delete-2
---------------------------------------------------------
B        |         3 |         5 |         2 |         2
C        |         5 |         5 |         6 |         7
E        |         4 |         5 |         5 |         3
---------------------------------------------------------

same.csv

filename | #insert-1 | #insert-2 | #delete-1 | #delete-2
---------------------------------------------------------
A        |         4 |         4 |         3 |         3
D        |         2 |         2 |         3 |         3
---------------------------------------------------------

Это мой код:

df_different = []
df_same = []
for row in range(0, len(mydataframe)):
    ins_1 = mydataframe.iloc[row][1]
    ins_2 = mydataframe.iloc[row][2]
    del_1 = mydataframe.iloc[row][3]
    del_2 = mydataframe.iloc[row][4]
    if (ins_1 != ins_2) or (del_1 != del_2):
        df_different.append(mydataframe.iloc[row])
    else:
        df_same.append(mydataframe.iloc[row])

with open('different.csv','w') as diffcsv:
    writers = csv.writer(diffcsv, delimiter=',')
    writers.writerow(fields)
    for item in df_different:
        writers.writerow(item)

with open('same.csv','w') as diffcsv:
    writers = csv.writer(diffcsv, delimiter=',')
    writers.writerow(fields)
    for item in df_same:
        writers.writerow(item)

На самом деле код работает хорошо, но когда набор данных очень большой (у меня есть миллионы данных), выполнение занимает очень много времени (более 3 часов). У меня вопрос, есть ли способ сделать это быстрее. Спасибо.

Ответы [ 3 ]

0 голосов
/ 04 июля 2018

Избегайте итерации по строкам; это довольно медленно Вместо этого векторизовать операцию сравнения:

same_mask = (df["#insert-1"] == df["#insert-2"]) & (df["#delete-1"] == df["#delete-2"])
df.loc[same_mask].to_csv("same.csv", index=False)
df.loc[~same_mask].to_csv("different.csv", index=False)

Для кадра данных из 1М строк это занимает всего несколько секунд.

0 голосов
/ 04 июля 2018

Использовать напрямую запрос фрейма данных:

Кадр Same_data:

same_dataframe = mydataframe[(mydataframe["insert1"] == mydataframe["insert2"]) & (mydataframe["delete1"] == mydataframe["delete2"])]

Другой датафрейм:

different_data = mydataframe[(mydataframe["insert1"] != mydataframe["insert2"]) | (mydataframe["delete1"] != mydataframe["delete2"])]

Я думаю, это быстрее, чем итерация.

Надеюсь, это поможет.

0 голосов
/ 04 июля 2018

Одна из простых вещей, которую вы можете сделать, - предоставить достаточно большие буферы, чтобы функция open (buffering=64*1024*1024) могла помочь (буфер 64 МБ).

Другая вещь - это итерация по фрейму данных - вместо итерации по номерам строк вы можете выполнять итерацию непосредственно по строкам , например:

for index, row in mydataframe.iterrows():
    ins_1 = row[1]
    ins_2 = row[2]
    del_1 = row[3]
    del_2 = row[4]

Я ожидаю, что это будет намного быстрее.

...