2017-10-15 28 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文件的性能更高。