簡體   English   中英

Pandas DataFrame 將 function 應用於多列和 Z78E6221F6393D1356DZ681DB398F14CE

[英]Pandas DataFrame apply function to multiple columns and output multiple columns

I have been scouring SO for the best way of applying a function that takes multiple separate Pandas DataFrame columns and outputs multiple new columns in the same said DataFrame. 假設我有以下內容:

def apply_func_to_df(df):
    df[['new_A', 'new_B']] = df.apply(lambda x: transform_func(x['A'], x['B'], x['C']), axis=1)

def transform_func(value_A, value_B, value_C):
    # do some processing and transformation and stuff
    return new_value_A, new_value_B

我正在嘗試將此 function 如上所示應用於整個 DataFrame df ,以便 output 2 個新列。 但是,這可以推廣到一個用例/函數,它接收n DataFrame 列並將m個新列輸出到相同的 DataFrame。

以下是我一直在關注的事情(取得了不同程度的成功):

  • 為 function 調用創建 Pandas 系列,然后將 append 到現有的 ZBA834BA059A9A379459ZC112E
  • Zip output 列(但在我當前的實現中發生了一些問題)
  • 重寫基本的 function transform_func以明確期望行(即字段) ABC如下,然后對df進行應用:

def transform_func_mod(df_row):
    # do something with df_row['A'], df_row['B'], df_row['C]
    return new_value_A, new_value_B

我想要一種非常通用和 Pythonic 的方式來完成這項任務,同時考慮性能(內存和時間方面)。 我將不勝感激任何輸入,因為我一直在努力解決這個問題,因為我不熟悉 Pandas。

按以下方式編寫您的transform_func

  • 它應該有一個參數 - 當前行,
  • 這個 function 可以從當前行讀取各個列並對其進行任何使用,
  • 返回的 object 應該是一個系列
    • values - 無論你想返回什么,
    • index - 目標列名。

示例:假設所有 3 列都是字符串類型,連接AB列,將“一些字符串”添加到C

def transform_func(row):
    a = row.A; b = row.B; c = row.C;
    return pd.Series([ a + b, c + '_xx'], index=['new_A', 'new_B'])

獲取新值,請將此 function 應用於每一行:

df.apply(transform_func, axis=1)

請注意,生成的 DataFrame 保留了原始行的鍵(我們稍后將使用此功能)。

或者,如果您想這些新列添加到 DataFrame 中,請將您的df與上述應用程序的結果連接起來,將連接結果保存在原始df下:

df = df.join(df.apply(transform_func, axis=1))

從 03:36:34Z 開始按照評論進行編輯

使用zip可能是最慢的選擇。 基於行的 function 應該更快,並且是更直觀的構造。 可能最快的方法是分別為每一列編寫 2 個向量化表達式。 在這種情況下,類似於:

df['new_A'] = df.A + df.B
df['new_B'] = df.C + '_xx'

但通常問題是基於行的 function 是否可以表示為矢量化表達式(正如我上面所做的那樣)。 在“否定”情況下,您可以應用基於行的 function。

要比較每個解決方案的速度,請使用%timeit

這個問題似乎與這個問題有些相關。 我參考了@spen.smith 在這個答案上的評論。

df = pd.DataFrame([[1,2,3], [2,3,4], [3,5,7]], columns = ['A', 'B', 'C'])
print(df)

   A  B  C
0  1  2  3
1  2  3  4
2  3  5  7

與其修改 function 的返回值,不如照常創建

def add_subtract(args):
    arg1, arg2 = args

    ret1 = arg1 + arg2
    ret2 = arg1 - arg2

    return ret1, ret2

檢查使用apply的 output 。 選項result_type='expand'將結果返回為 dataframe 而不是一系列元組。

print(df[['B', 'C']].apply(add_subtract, axis=1, result_type='expand'))

    0  1
0   5 -1
1   7 -1
2  12 -2

然后,我們可以通過轉置然后訪問值將apply output 的列分配給兩個新系列。 轉置是必要的,因為調用values的默認行為將每一行視為一個列表,而我們希望每一列都作為一個列表。 所以最終的表達式是:

df['D'], df['E'] = df[['B', 'C']].apply(add_subtract, axis=1, result_type='expand').transpose().values
print(df)

   A  B  C   D  E
0  1  2  3   5 -1
1  2  3  4   7 -1
2  3  5  7  12 -2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM