这8行python+pandas需要~1个月才能执行,能帮我加速吗?

2024-04-24 03:06:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个30GB的csv文件,2列,80M行。一列有8000万个唯一元素(电子邮件),另一列有500万个uniques(匿名发件人),8000万个元素将多个元素映射到一个元素。我想输出一个只有500万行的csv:发件人,发件人发送的电子邮件

这段代码在理论上是有效的,但实际上要用一个100%的Xeon CPU内核完成大约需要1个月的时间

df = pd.read_csv('emails.csv')
uni = df.sender_id.unique()
grouped = ((i, ' '.join(df.text[df.sender_id == i])) for i in uni)
with open('/storage/test.csv', 'w') as csvfile:
    test_writer = csv.writer(csvfile)
    for i in grouped:
        test_writer.writerow(i)
csvfile.close()

你知道怎么做得更快吗?我试过用joblib并行化它,但是内存用完了。你知道吗


Tags: 文件csvcsvfileintestid元素df
2条回答

我发现这行代码有问题:

grouped = ((i, ' '.join(df.text[df.sender_id == i])) for i in uni)

需要0(80M x 5M)才能执行。对于每一个发送者,它会遍历所有8000万条消息来匹配发送者,并加入匹配的电子邮件。你知道吗

相反,您只能反复浏览电子邮件一次:

from collections import defaultdict

df = pd.read_csv('emails.csv')
grouped = defaultdict(str)
for i, text in zip(df.sender_id, df.text):
    grouped[i] += text + ' '

with open('/storage/test.csv', 'w') as csvfile:
    test_writer = csv.writer(csvfile)
    for i in grouped.items():  # use iteritems in Python2
        test_writer.writerow(i)

如果cvsfile来自“with”语句,我认为不需要显式关闭它。感谢njzk2推荐defaultdict。你知道吗

通过使用pandas groupby/apply并从生成的数据帧中写入csv,我在一个简单的N=10000测试用例上获得了大约5倍的速度提升:

df = pd.read_csv('emails.csv')
grouped = df.groupby('sender_id').apply(lambda group: ' '.join(group.text))
grouped.to_csv('/storage/test.csv')

我会从这个开始,如果不够的话继续优化。如果内存是一个问题,那么您可以求助于^{},它提供了一个类似熊猫的接口,可以对数据帧进行直接的核心外/分布式计算。你知道吗

相关问题 更多 >