遍历列的有效方法

时间:2020-09-23 20:28:37

标签: python pandas loops

我的数据集如下:

import pandas as pd
data = {'stringID':['AB CD Efdadasfd','RFDS EDSfdsadf dsa','FDSADFDSADFFDSA']}
data = pd.DataFrame(data)
data['Index1'] = [[3,6],[7,9],[5,6]]
data['Index2'] = [[4,8],[10,13],[8,9]]

enter image description here

然后我根据Index1和Index2(均为列表)中的值计算了容量,我正在使用索引从stringID列中切片子字符串。目前,这是我的计算结果:

data['Value1'] = [data['stringID'][i][data['Index1'][i][0]:data['Index2'][i][0]] for i in range(0,len(data['stringID']))]

enter image description here

它可以工作,但是如果我遍历一个大型数据集,它会非常慢。有什么更好的方法呢?谢谢!

2 个答案:

答案 0 :(得分:2)

修改

正如您所说的,您的真实数据集有3列以上,您只需要对3列进行切片,然后按以下方式获取numpy nd-array:

data['Value1'] = [x[y[0]:z[0]] for x, y, z 
                           in  data[['stringID','Index1','Index2']].to_numpy()]

您不能避免循环。但是,您可以使用numpy nd-array作为源来简化列表理解,例如

data['Value1'] = [x[y[0]:z[0]] for x,y,z in data.to_numpy()]

对30万行计时

data = pd.concat([data]*100000, ignore_index=True)

In [1380]: %timeit [x[y[0]:z[0]] for x,y,z in data.to_numpy()]
617 ms ± 24.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [1382]: %timeit  [data['stringID'][i][data['Index1'][i][0]:data['Index2'][i][0]] for i in range(0,len(data['stringID']))]
11.3 s ± 320 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

因此,它比解决方案快18倍。

答案 1 :(得分:1)

您可以使用DataFrame.apply

data['Value1'] = data.apply(lambda d: d['stringID'][d['Index1'][0]:d['Index2'][0]], axis=1)

您可以预处理索引以用于在另一列中切片

from operator import itemgetter

data['slice'] = list(zip(data['Index1'].apply(itemgetter(0)), data['Index2'].apply(itemgetter(0))))
data['Value1'] = data.apply(lambda d: d['stringID'][slice(*d['slice'])], axis=1)

或将切片对象直接存储在另一列中

data['slice'] = list(map(lambda x: slice(*x), zip(data['Index1'].apply(itemgetter(0)), 
                                                  data['Index2'].apply(itemgetter(0)))))


data['Value1'] = data.apply(lambda d: d['stringID'][d['slice']], axis=1)