我想从一个大的 csv 中删除重复项。我有这个 csv 格式的数据
client_id;gender;age;profese;addr_cntry;NAZOKRESU;prijem_AVG_6M_pasmo;cont_id;main_prod_id;bal_actl_am_pasmo
388713248;F;80;důchodce;CZ;Czech;;5715125;39775;
27953927;M;28;Dělník;CZ;Opavia;22;4427292;39075;
我需要删除 client_id 中的所有重复项。 我无法用 Pandas 在 python 中处理这个大文件。我尝试了 dask,但结果相同。只是无限的等待时间,什么也没发生。
这是我的最后一个版本的代码
import dask.dataframe as dd
import chardet
from dask.diagnostics import ProgressBar
with open('bigData.csv', 'rb') as f:
result = chardet.detect(f.read())
df = dd.read_csv('bigData.csv', encoding=result['encoding'], sep=';')
total_rows = df.shape[0].compute()
df = df.drop_duplicates(subset=['client_id'], keep=False, Inplace=True)
df.to_csv('bigData.csv', sep=';', index=False)
total_duplicates = total_rows - df.shape[0].compute()
print(f'Was deleted {total_duplicates} duplicated rows.')
我用进度条尝试了一下,但什么也没发生。感谢您的帮助!
您也许可以使用一个非常简单的 Python 程序,该程序将它在字典中看到的每个新 ID 存储起来,如果发现该行的 ID 已在字典中,则跳过写入后续行。 它应该需要大约 2GB 的 RAM。
import csv
reader = csv.reader(open("input.csv", newline=""))
writer = csv.writer(open("output.csv", "w", newline=""))
writer.writerow(next(reader)) # transfer header, if you have one
ids = {}
for row in reader:
if row[0] not in ids:
writer.writerow(row)
ids[row[0]] = None # add ID to "list" of already written IDs
这个方法:
ids
来保存程序已经遇到并写入的所有ID; dicts 可以非常快速地查找/检查其键(您的 ID)。我模拟了一个 CSV w/20M 行(随机生成的 ID 在 0 到 20M 之间),看起来像这样:
| id | i |
|----------|---|
| 2266768 | 0 |
| 15245359 | 1 |
| 16304974 | 2 |
| 4801643 | 3 |
| 9612409 | 4 |
| 17659151 | 5 |
| 15824934 | 6 |
| 4101873 | 7 |
| 12282127 | 8 |
| 5172219 | 9 |
我通过该程序运行它,最终得到 1260 万行。 在我的 Macbook Air M1(双通道 SSD)上,耗时 14 秒,消耗 1.5GB RAM。 RAM 需要保存所有以前见过的 ID。
另外,我看到您首先读取整个文件以检测字符编码:
您是否尝试过从命令行运行
chardetect
,chardetect input.csv
,然后对返回的值进行硬编码?
您是否尝试过读取文件的一小部分并查看获得的结果和信心?
with open("input.csv", "rb") as f:
input_enc = chardet.detect(f.read(1024 * 64)) # only read first 64K
print(input_enc) # {'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
使用 AWK 执行相同的任务。这不是操作员要求的,只是为了完成上面的评论。 不接受作为答案。
BEGIN{
FS="," # set field separator to comma
}
!seen[$2]++ { # is field 2 not seen before ?
print $0
}
样本数据:
RowNum,ID
1,5220607
2,8632078
3,8323076
..
运行为
c:\>awk -f script.awk input.csv > uniquevalues.csv
这会输出大约 12 mio 行,并在大约 18 秒内消耗 1,8GB 内存(i7 Windows)。
上面 @zach-young 的 python 脚本在同一台计算机和文件上大约需要 35 秒,但内存较少。
使用 DuckDB 在一个 SQL 查询中可以非常高效地完成此操作
COPY (SELECT DISTINCT * FROM read_csv_auto('bigfile.csv')) TO 'dedupedFile.csv' (HEADER, DELIMITER ',');
也可以在Python中使用