遍历应用函数的数据框的每一列并将结果另存为新列

时间:2018-08-18 16:53:39

标签: python pandas dataframe apply

我使用了以下两行代码来计算公式的值,并将结果另存为同一数据框中的新列。该公式将数据帧(df_H)的每一列的值乘以字典(H)中的值,然后将这些值(单行)相加,然后将其除以字典中所有值的总和,然后保存结果在新列的同一行中(df_H [“ COI”])。

    H = {'G1_H':9.5438, 'G2_H':3.921565, 'G3_H':2.939454}
    df_H['COI'] = pd.Series(((df_H.G1 * H['G1_H']) + (df_H.G3 *H['G3_H']) + ...)/(H['G1_H']+H['G3_H']+...), index=df_H.index)

现在,我想重新编写相同的代码,以便它遍历所有列并执行相同的操作。列的数量和字典的项目基于模拟而变化,但是,列的数量始终等于字典的项目的数量。

1 个答案:

答案 0 :(得分:1)

使方法更通用的一种方法是进行标量*列乘法,而不必显式命名每个列。

如果您可以确定自己的H字典键始终与您的DataFrame列名完全匹配,请尝试以下操作:

# Multiply each DF column with its corresponding dict value
temp = df_H.transform(lambda x: x * H[x.name])
# Add up transformed rows and divide by the sum of all dict values
df_H['COI'] = temp.sum(axis=1) / sum(H.values())

可运行的示例

df_H = pd.DataFrame({'G1_H': [0, 1, 2, 3], 'G2_H': [2, 4, 6, 8], 'G3_H': [-1, 0, 1, 2]})
H = dict(G1_H=1, G2_H=2, G3_H=3)

temp = df_H.transform(lambda x: x * H[x.name])
df_H['COI'] = temp.sum(axis=1) / sum(H.values())

H
{'G1_H': 1, 'G2_H': 2, 'G3_H': 3}

temp
   G1_H  G2_H  G3_H
0     0     4    -3
1     1     8     0
2     2    12     3
3     3    16     6

df_H
   G1_H  G2_H  G3_H       COI
0     0     2    -1  0.166667
1     1     4     0  1.500000
2     2     6     1  2.833333
3     3     8     2  4.166667

罗义解释

temp = df_H.transform(lambda x: x * H[x.name])

df.transform()的工作是处理df的每个,对于每列,返回与输入列长度相同的结果。因此,运行df.transform()始终会导致DataFrame具有相同的形状。

df.transform()接受一个函数,在这种情况下是lambda函数(该函数没有就地定义名称,而与def func_name(arg1):中的函数相反)。

lambda x: x * H[x.name]x中的每一列“ df”说,将其乘以关键字为x.name的字典值,该字典值是每一列的名称。 (请记住,DataFrame中的列只是Series,并且每个列的名称都可以通过Series.name来访问。)该函数起作用是因为您的python字典H具有完全相同的键匹配DF中的列。

df_H['COI'] = temp.sum(axis=1) / sum(H.values())

按操作顺序,此行首先将temp的每个 row 中的值相加(由于axis=1),从而导致Series中只有一列它。 (大多数熊猫方法的默认维是axis=0,它作用于每个中的值,在这里不起作用。)

然后,将求和的结果逐个元素除以所有字典值sum(H.values())的和,这是一个标量。 Pandas(实际上是numpy)知道通过除法操作跨向量“标量”标量,从而完成大多数人期望代码执行的操作(有关numpy广播的更多信息,请访问https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)。