2017-06-15 191 views
0

我正在嘗試將函數應用於數據框的每一行。棘手的部分是該函數爲每個處理後的行返回一個新的數據幀。假設這個數據框的列可以很容易地從處理過的行中派生出來。Python:將函數應用到Pandas DataFrame的每一行並返回**新數據框**

最後結果應該是所有這些數據幀(每個處理的行1個)連接起來。我故意不提供示例代碼,因爲最簡單的解決方案建議將會執行,只要「棘手」的部分得到滿足。

我花了數小時試圖挖掘文檔和計算器以找到解決方案。像往常一樣,熊貓文檔是沒有實際的例子,除了最簡單的操作,我無法弄清楚。我也確保不會錯過任何重複的問題。非常感謝。

+0

爲什麼你需要返回一個數據框,如果你只是在最後連接它們?在你的問題中沒有什麼解釋爲什麼這個「要求」是相關的。事實上,如果您正在考慮行而不是列,那麼您可能無效地處理數據。 – Alexander

+0

...你試過'pd.DataFrame.apply'方法嗎?它似乎*完全*你想要的。 –

+0

@亞歷山大我其實確實需要這個要求。 考慮這個炮製的例子:數據表中的每一行都是一個人的名字。要應用於每行的函數將採用該名稱,並且通過任何邏輯(引用外部對象/數據幀)將返回與該名稱關聯的5個數字特徵。現在我非常需要這個名稱和它的5個特徵,以DataFrame格式,即5行,2列:名稱|特徵 對於所有行也是如此。 –

回答

0

假設你正在申請的每一行的功能被稱爲f

pd.concat({i: f(row) for i, row in df.iterrows()}) 

工作實例

df = pd.DataFrame(np.arange(25).reshape(5, 5), columns=list('ABCDE')) 

def f(row): 
    return pd.concat([row] * 2, keys=['x', 'y']).unstack().drop('C', 1).assign(S=99) 

pd.concat({i: f(row) for i, row in df.iterrows()}) 

     A B D E S 
0 x 0 1 3 4 99 
    y 0 1 3 4 99 
1 x 5 6 8 9 99 
    y 5 6 8 9 99 
2 x 10 11 13 14 99 
    y 10 11 13 14 99 
3 x 15 16 18 19 99 
    y 15 16 18 19 99 
4 x 20 21 23 24 99 
    y 20 21 23 24 99 

或者

df.groupby(level=0).apply(lambda x: f(x.squeeze())) 


     A B D E S 
0 x 0 1 3 4 99 
    y 0 1 3 4 99 
1 x 5 6 8 9 99 
    y 5 6 8 9 99 
2 x 10 11 13 14 99 
    y 10 11 13 14 99 
3 x 15 16 18 19 99 
    y 15 16 18 19 99 
4 x 20 21 23 24 99 
    y 20 21 23 24 99 
0

我會做這種方式 - 雖然我注意到.apply可能是你正在尋找的東西。

import pandas as pd 
import numpy as np 

np.random.seed(7) 

orig=pd.DataFrame(np.random.rand(6,3)) 

orig.columns=(['F1','F2','F3']) 

res=[] 


for i,r in orig.iterrows(): 
    tot=0 
    for col in r: 
     tot=tot+col 
    rv={'res':tot} 
    a=pd.DataFrame.from_dict(rv,orient='index',dtype=np.float64) 
    res.append(a) 


res[0].head() 

應該返回像這樣

{'res':10} 
0

目前還不清楚你想達到什麼樣的,但我懷疑你需要創建單獨的dataframes。

下面的示例顯示瞭如何獲取數據框,將其子集合到您感興趣的列,將函數foo應用於其中一列,然後應用返回多個值的第二個函數bar

df = pd.DataFrame({ 
    'first_name': ['john', 'nancy', 'jolly'], 
    'last_name': ['smith', 'drew', 'rogers'], 
    'A': [1, 4, 7], 
    'B': [2, 5, 8], 
    'C': [3, 6, 9] 
}) 

>>> df 
first_name last_name A B C 
0 john smith 1 2 3 
1 nancy drew 4 5 6 
2 jolly rogers 7 8 9 

def foo(first_name): 
    return 2 if first_name.startswith('j') else 1 

def bar(first_name): 
    return (2, 0) if first_name.startswith('j') else (1, 3) 

columns_of_interest = ['first_name', 'A'] 

df_new = pd.concat([ 
    df[columns_of_interest].assign(x=df.first_name.apply(foo)), 
    df.first_name.apply(bar).apply(pd.Series)], axis=1) 

>>> df_new 
first_name A x 0 1 
0 john 1 2 2 0 
1 nancy 4 1 1 3 
2 jolly 7 2 2 0 
相關問題