【问题标题】:Pandas .loc taking a very long timePandas .loc 需要很长时间
【发布时间】:2018-10-16 19:20:45
【问题描述】:

我有一个 10 GB 的 csv 文件,其中包含 170,000,000 行和 23 列,我将其读入数据框,如下所示:

import pandas as pd 

d = pd.read_csv(f, dtype = {'tax_id': str})

我还有一个包含近 20,000 个独特元素的字符串列表:

h = ['1123787', '3345634442', '2342345234', .... ]

我想在数据框d 中创建一个名为class 的新列。只要d['tax_id'] 具有在字符串列表h 中找到的值,我就想分配d['class'] = 'A'。否则,我想要d['class'] = 'B'

以下代码在我的数据框d 的 1% 样本上运行得非常快:

d['class'] = 'B'
d.loc[d['tax_num'].isin(h), 'class'] = 'A' 

但是,在完整的数据帧 d 上,此代码需要 48 小时(并且还在继续)才能在 32 核服务器上以批处理模式运行。我怀疑使用loc 进行索引会减慢代码速度,但我不确定它到底是什么。

总之:有没有更有效的方法来创建class 列?

【问题讨论】:

  • Pandas 无法处理那么多数据。查看dask
  • 另一个问题,你的税号是唯一的吗?
  • 不确定这是否更好,但尝试使h 列表成为在h 内容上索引的第二个数据帧,然后使tax_num 成为d 上的索引,然后尝试join().
  • @coldspeed 是的,我在列表 h 中的税号是唯一的。
  • 是的,pandas 支持非唯一索引。

标签: python pandas select indexing


【解决方案1】:

如果您的税号是唯一的,我建议将tax_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 切换到分布式处理。

【讨论】:

  • 当我尝试这个时,我收到以下错误:KeyError: "['352210820' '262816852' '097589434' ... '640789106' '593155203'\n '362812803'] not in index" 我认为这是因为并非h 中的所有值都在d['tax_num'] 中。有没有办法解决这个问题?
  • @svenkatesh 你可以做和交集:h2 = df.index.intersection(h) 然后用 h2 索引。
  • @svenkatesh 哦,有用吗?出于好奇,这次改动用了多长时间?
  • @coldspeed 这很好用,谢谢!您答案中的三行代码耗时 2.201 小时。总运行时间(包括文件 IO)耗时 3.671 小时。
  • @svenkatesh 有趣的注释;我会记住这一点。 set.intersection 通常非常快。顺便说一句,如果您的 tax_num 是唯一的,那么 d['tax_num'].unique() 是不必要的开销:) set(h).intersection(d['tax_num']) 应该这样做,或者等效地,set(h).intersection(d['tax_num'].tolist())
【解决方案2】:

“我还有一个包含近 20,000 个独特元素的字符串列表”

好吧,首先,如果您打算将该列表用于成员资格测试,您应该将该列表设为setlist 对象具有线性时间成员资格测试,set 对象具有非常优化的成员资格测试的恒定时间性能。这是这里最容易实现的目标。所以用

h = set(h) # convert list to set
d['class'] = 'B'
d.loc[d['tax_num'].isin(h), 'class'] = 'A' 

【讨论】:

  • 我的猜测是使用numpy.isin() 应该比set 快得多。我在小实例上尝试过。 numpy.isin(df["column"], selection) 原来是 80 微秒,而使用 df["column"].isin(set(selection)) 是 130 微秒
猜你喜欢
  • 2018-09-15
  • 2013-09-07
  • 2020-08-26
  • 2014-10-09
  • 2012-11-26
  • 2019-12-27
  • 2017-10-22
  • 2020-11-15
  • 2016-05-19
相关资源
最近更新 更多