Python 熊猫。要花很长时间
我有一个10 GB的csv文件,其中包含Python 熊猫。要花很长时间,python,pandas,select,indexing,Python,Pandas,Select,Indexing,我有一个10 GB的csv文件,其中包含170000000行和23列,我将其读入数据帧,如下所示: import pandas as pd d = pd.read_csv(f, dtype = {'tax_id': str}) 我还有一个包含近20000个独特元素的字符串列表: h = ['1123787', '3345634442', '2342345234', .... ] 我想在数据框d中创建一个名为class的新列。每当d['tax\u id']具有字符串列表中的值时,我想分配d
170000000
行和23
列,我将其读入数据帧,如下所示:
import pandas as pd
d = pd.read_csv(f, dtype = {'tax_id': str})
我还有一个包含近20000个独特元素的字符串列表:
h = ['1123787', '3345634442', '2342345234', .... ]
我想在数据框d
中创建一个名为class
的新列。每当d['tax\u id']
具有字符串列表中的值时,我想分配d['class']='A'
。否则,我希望d['class']='B'
以下代码在我的数据帧d
的1%样本上运行得非常快:
d['class'] = 'B'
d.loc[d['tax_num'].isin(h), 'class'] = 'A'
但是,在完整的数据帧d
上,此代码在32核服务器上以批处理模式运行需要超过48小时(并且正在计算)。我怀疑使用loc
进行索引会减慢代码的速度,但我不确定它到底是什么
总之:是否有更有效的方法创建
类
列 如果您的税号是唯一的,我建议将tax\u num
设置为索引,然后在此基础上建立索引。目前,您调用isin
,这是一种线性操作。无论你的机器有多快,它都无法在合理的时间内对1.7亿条记录进行线性搜索
df.set_index('tax_num', inplace=True) # df = df.set_index('tax_num')
df['class'] = 'B'
df.loc[h, 'class'] = 'A'
如果您仍然存在性能问题,我建议您使用dask
切换到分布式处理
“我还有一个包含近20000个唯一元素的字符串列表”
首先,如果您打算将该列表用于成员资格测试,您应该将其设置为一个集合<代码>列表
对象具有线性时间成员身份测试,集合
对象具有非常优化的恒定时间成员身份测试性能。这是这里挂得最低的水果。所以使用
h = set(h) # convert list to set
d['class'] = 'B'
d.loc[d['tax_num'].isin(h), 'class'] = 'A'
熊猫无法处理那么多数据。查看
dask
。另一个问题,您的税号是唯一的吗?不确定这是否更好,但请尝试将h
列表作为在h
内容上索引的第二个数据帧,然后将tax\u num
设置为d
上的索引,然后尝试ajoin()
@coldspeed-yup,我在列表h中的税号是唯一的。是的,pandas支持非唯一索引。当我尝试此操作时,我得到以下错误:KeyError:“['352210820''262816852''097589434'…'640789106''593155203'\n'362812803']不在索引中”
我认为这是因为h
中的值并非都在d['tax\u num'
中。有什么办法可以解决这个问题吗?@svenkatesh你可以做和交叉点:h2=df.index.intersection(h),然后用h2进行索引。@svenkatesh哦,行了吗?出于好奇,这项改变花了多长时间?@coldspeed这项工作做得很好,谢谢!你答案中的三行代码花了2.201小时。总运行时间(包括文件IO)花费了3.671小时。@svenkatesh有趣的注释;我会记住这一点<代码>设置。交叉口通常非常快。顺便说一句,如果你的税号是唯一的,那么d['tax\u num'].unique()
是一个不必要的开销:)set(h)。交集(d['tax\u num']
应该做,或者等效地说,set(h)。交集(d['tax\u num'].tolist())
我猜使用的是numpy.isin()
应该比集快得多。我试了一个小例子<代码>numpy.isin(df[“column”],selection)
使用df[“column”]。isin(set(selection))