我使用了以下两行代码来计算公式的值,并将结果另存为同一数据框中的新列。该公式将数据帧(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)
现在,我想重新编写相同的代码,以便它遍历所有列并执行相同的操作。列的数量和字典的项目基于模拟而变化,但是,列的数量始终等于字典的项目的数量。
答案 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)。