2016-12-24 104 views
3

我需要將多個函數應用於數據幀行。這些函數的參數從單個行的兩個或多個字段獲取值。例如:Python Pandas:將函數應用於數據幀行時返回多個字段值

d = {                          
    'a': [1,1,1,1],                       
    'b': [2,2,2,2],                       
    'c': [3,3,3,3],                       
    'd': [4,4,4,4]                        
}                           

df1 = pd.DataFrame(d)                      

def f1(x,y):                         
    return x + 2*y                       

def f2(x,y):                         
    return y + 2*x                       

df2 = pd.DataFrame()                       
df2['val1'] = df1.apply(lambda r: f1(r.a, r.b),1)               
df2['val2'] = df1.apply(lambda r: f2(r.c, r.d),1)               

當依次應用每個函數時,Pandas會對所有數據幀行進行單獨迭代。在這個例子中熊貓迭代數據幀兩次。因此,我得到:

In [10]: df2                         
Out[10]:                          
    val1 val2                        
0  5 10                        
1  5 10                        
2  5 10                        
3  5 10                        

有沒有什麼辦法可以在數據幀上單次傳遞兩個或更多的函數?這樣,應用程序應該爲一行中的多個字段返回值。此外,這種情況包括應用一個函數返回超過一個字段的值。如何才能做到這一點?

回答

0

如果你的函數是線性的或者可以用某種方式進行矢量化,我們可以做很多很酷的事情。

t = pd.DataFrame(dict(val1=[1, 2, 0, 0], val2=[0, 0, 2, 1]), df1.columns) 
df1.dot(t) 

或用

pd.DataFrame(
    df1.values.dot(
     np.array([[1, 0], [2, 0], [0, 2], [0, 1]]) 
    ), 
    df1.index, 
    ['val1', 'val2'] 
) 

enter image description here

,也可以定義更快的新功能,通過組合應用

def f3(r): 
    return pd.Series(dict(val1=f1(r.a, r.b), val2=f2(r.c, r.d))) 

df1.apply(f3, 1) 
+1

想這一次是關於我的MacBookPro6,2,英特爾酷睿i5 2 74MB csv文件, 53,處理器:1,內核:2,L2緩存(每核):256 KB,L3緩存:3 MB,內存:4 GB。在OSX EL Capitan版本下。 10.11.6。一個接一個的函數應用程序的工作會更糟糕。總共消耗了大約6GB的內存並從未完成,只好殺了。美學上這個解決方案看起來不錯,對我來說最易讀。我認爲這種降級是由於字典和系列對象需要額外的內存分配。 – zork

+0

@ zork很高興知道。這些是你需要的實際功能嗎?如果是的話,我們可以很容易地將這個向量化。 – piRSquared

+0

不,功能不同... – zork

1

你可以在同一時間填補他們的功能:

def f3(x,y,z,a): 
    return x + 2*y, a + 2*z 
df3 = pd.DataFrame() 
df3['val1'], df3['val2'] = f3(df1.a, df1.b, df1.c, df1.d) 
+1

這是一個好方法,但不是每個函數都可以在dataFrame上像這樣運行。 也可以像'df3 ['val1'],df3 ['val2'] = f1(df1.a,df1.b),f2(df1.c,df1.d)' –

+0

'與我的實際功能和論點。我得到這個錯誤:'/Users/user/usr/anaconda_2.7/anaconda/lib/python2.7/site-packages/pandas/core/generic.pyc in __getattr __(self,name) 2670 if self in self。 _info_axis: 2671返回自[名稱] - > 2672返回對象.__的getAttribute __(個體,名稱) 2674 DEF __setattr __(個體,名稱,值): AttributeError的:「系列的對象沒有屬性 '分裂' ' – zork

0

如果您不希望創建新的功能,你可以使用下面的一行:

>>> df2 = df1.apply(lambda r: pd.Series({'val1': f1(r.a, r.b), 'val2': f2(r.c, r.d)}), axis=1) 
>>> df2 
    val1 val2 
0  5 10 
1  5 10 
2  5 10 
3  5 10 
相關問題