2017-10-15 27 views
-3

我有一个有10列和大约20,000,000行的数据框。 我需要逐行比较10列的值,并用新值创建5列。为此,我定义了一个由if函数组成的函数并应用它来测试每个函数。如何测试每列的列值?

例如:

>>> import pandas as pd 
>>> df = pd.DataFrame({'a':[1,2,3,4,5], 'b':[11,12,13,14,16], 'c':[21,22,23,24,25], 'd':[31,32,33,34,35]) 


>>> def cal1(row): 
>>>  v1=0 
>>>  v2=0 
>>>  if 0< row['a'] <2: 
>>>   v1=1 
>>>  if 11< row['b'] <14: 
>>>   v2=1 
>>>  return v1+v2 


>>> def cal2(row): 
>>>  v1=0 
>>>  v2=0 
>>>  if 2<= row['a'] <4: 
>>>   v1=-1 
>>>  if 14<= row['b']<=16: 
>>>   v2=-1 
>>>  return v1+v2  

>>> df['n1'] = df.apply(ca11, axis=1) 
>>> df['n2'] = df.apply(cal2, axis=1) 

我能得到答案这种方式,但我需要5个定义的函数,每个条件一个长长的清单。计算过于缓慢。 (实际数据应在所有10列上进行测试,并且至少有10个条件。)

有没有更好的方法来逐行测试每列中的数据?

回答

0

IIUC,你有一致的值你想分配给每一行。例如,n10,12。如果是这种情况,您可以开始n10并添加索引:

df['n1'] = 0 

mask1 = df.a.between(0, 2, inclusive=False) 
mask2 = df.b.between(11, 14, inclusive=False) 

df.loc[mask1 | mask2, 'n1'] = 1 
df.loc[mask1 & mask2, 'n1'] = 2 
0

apply()接受几个parametersfunc并且还args,这是

位置参数传递除了阵列/系列起作用

你可以可以传递例如(0, 2, 11, 14)以允许更通用的功能为列B评分,对于列B评分(2, 4, 14, 16)等等。或者,传入列名称并让函数根据该名称作出决定。

处理20 M行有相当多的CPU开销和内存占用量。您可能会发现使用csvreader读取要评分的每一行并使用csvwriter发出结果并使pandas导入扩充的CSV文件的性能更高。