首页 > 解决方案 > 将函数应用于数据框的每一行并将数据存储到 Python 中的列表/数据框

问题描述

我有以下简化版本的代码:

import pandas as pd


def myFunction(portf, Val):
    mydata = {portf: [Val, Val * 2, Val * 3, Val * 4]}
    df = pd.DataFrame(mydata, columns=[portf])
    return df


data = {'Portfolio':  ['Book1', 'Book2', 'Book1', 'Book2'],
        'Value':      [10,      5,       6,       11]}
df_input = pd.DataFrame(data, columns=['Portfolio', 'Value'])

df_output = myFunction(df_input['Portfolio'][0], df_input['Value'][0])
df_output1 = myFunction(df_input['Portfolio'][1], df_input['Value'][1])
df_output2 = myFunction(df_input['Portfolio'][2], df_input['Value'][2])
df_output3 = myFunction(df_input['Portfolio'][3], df_input['Value'][3])

我想要的是以有效的方式将所有 df_output 连接到一个列表中,甚至更好地连接到一个数据框中,因为 df_input 数据框将有 100 多列。

我尝试应用以下内容:

df_input.apply(lambda row : myFunction(row['Portfolio'], row['Value']), axis = 1)

但是,所有结果都返回到单个列。

知道如何实现吗?

谢谢

标签: python-3.xpandasdataframe

解决方案


您可以使用 pd.concat 将所有结果存储在单个数据框中:

pd.concat([myFunction(row['Portfolio'], row['Value']) 
           for _, row in df_input.iterrows()], axis=1)

首先,您使用列表推导构建一个 pd.DataFrames 列表(您也可以使用普通循环)。然后你沿着axis=1连接所有数据帧。

输出:

    Book1   Book2   Book1   Book2
0   10      5       6       11
1   20      10      12      22
2   30      15      18      33
3   40      20      24      44

您提到 df_input 在原始数据框中有更多行。为了解决这个问题,您需要另一个循环(最小示例):

data = {'Portfolio':  ['Book1', 'Book2', 'Book1', 'Book2'],
        'Value':      [10,      5,       6,       11]}
df_input = pd.DataFrame(data, columns=['Portfolio', 'Value'])
df_input['Value2'] = df_input['Value'] * 100

pd.concat([myFunction(row['Portfolio'], row[col]) 
           for col in df_input.columns if col != 'Portfolio'
           for (_, row) in df_input.iterrows()], axis=1)

输出:

    Book1   Book2   Book1   Book2   Book1   Book2   Book1   Book2
0   10      5       6       11      1000    500     600     1100
1   20      10      12      22      2000    1000    1200    2200
2   30      15      18      33      3000    1500    1800    3300
3   40      20      24      44      4000    2000    2400    4400

您可能希望重命名列或以其他方式聚合生成的数据框。但为此我不得不猜测(面对模棱两可的情况,我尽量不去猜测)。


推荐阅读