我有一个包含170,000,000
行和23
列的10 GB csv文件,我将其读入数据框,如下所示:
import pandas as pd
d = pd.read_csv(f, dtype = {'tax_id': str})
我还有一个包含近20,000个独特元素的字符串列表:
h = ['1123787', '3345634442', '2342345234', .... ]
我想在数据框class
中创建一个名为d
的新列。每当d['class'] = 'A'
具有在字符串d['tax_id']
中找到的值时,我想分配h
。否则,我想要d['class'] = 'B'
。
以下代码可以快速处理我的数据框{1}的1%样本:
d
但是,在完整的数据帧d['class'] = 'B'
d.loc[d['tax_num'].isin(h), 'class'] = 'A'
上,此代码需要48小时(并且计数)以批处理模式在32核服务器上运行。我怀疑使用d
建立索引会降低代码速度,但我不确定它究竟是什么。
总之:是否有更有效的方法来创建loc
列?
答案 0 :(得分:2)
如果您的税号是唯一的,我建议将pd.DataFrame([np.mean(x.reshape(len(df)//4,-1),axis=1) for x in df.values.T]).T
0 1
0 3.75 0.65
1 10.25 1.05
2 16.00 1.45
3 21.25 1.85
4 29.75 2.25
设置为索引,然后对其进行索引。就目前而言,您调用tax_num
这是一个线性操作。无论您的机器速度如何,它都无法在合理的时间内对1.7亿条记录进行线性搜索。
isin
如果您仍然遇到性能问题,我建议您使用df.set_index('tax_num', inplace=True) # df = df.set_index('tax_num')
df['class'] = 'B'
df.loc[h, 'class'] = 'A'
切换到分布式处理。
答案 1 :(得分:1)
“我还有一个包含近20,000个独特元素的字符串列表”
嗯,对于初学者,如果您要将其用于成员资格测试,则应将该列表设为set
。 list
个对象具有线性时间成员资格测试,set
个对象具有非常优化的常量时间性能,可用于成员资格测试。那是这里最低的水果。所以使用
h = set(h) # convert list to set
d['class'] = 'B'
d.loc[d['tax_num'].isin(h), 'class'] = 'A'