我有一个DataFrame看起来像:
import pandas as pd
df = pd.DataFrame([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0],
[9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0],
[17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0]],
columns=['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'])
A B C D E F G H
0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0
1 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0
2 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0
我有一个列列表:
l = ['A', 'C', 'D', 'E']
对于列表中的每个元素,我想获取其前面的数据框列的平均值,再加上其自己列中的值的两倍。因此,
A
仅取决于自身,C
将取决于A
及其本身,D
将取决于A
,C
及其自身的总和,而E
将取决于A
,C
,D
及其本身。我通过以下方式完成了我所需要的:for i, col in enumerate(l):
other_cols = l[:i]
df['tmp_' + col] = df[other_cols].mean(axis=1) + 2.0 * df[col]
A B C D E F G H tmp_A tmp_C tmp_D \
0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 NaN 7.0 10.0
1 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 NaN 31.0 34.0
2 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0 NaN 55.0 58.0
tmp_E
0 12.666667
1 36.666667
2 60.666667
我想知道是否还有一种更Python化的方法来完成相同的事情,而不必执行for循环?
最佳答案
IIUC,您可以在现代熊猫中使用expanding
来处理此问题:
>>> cols = ["A","C","D","E"]
>>> df[cols] * 2 + df[cols].expanding(axis=1).mean().shift(axis=1).fillna(0)
A C D E
0 2.0 7.0 10.0 12.666667
1 18.0 31.0 34.0 36.666667
2 34.0 55.0 58.0 60.666667
这将重现您预期的新列(由于fillna将NaN变为0,A变为其原始值的两倍)。
我们可以逐步了解它的来源:
从...开始
>>> df[cols]
A C D E
0 1.0 3.0 4.0 5.0
1 9.0 11.0 12.0 13.0
2 17.0 19.0 20.0 21.0
>>> df[cols].expanding(axis=1)
Expanding [min_periods=1,center=False,axis=1]
我们可以先做
sum
,因为它在视觉上更容易检查:>>> df[cols].expanding(axis=1).sum()
A C D E
0 1.0 4.0 8.0 12.0
1 9.0 20.0 32.0 36.0
2 17.0 36.0 56.0 60.0
>>> df[cols].expanding(axis=1).mean()
A C D E
0 1.0 2.0 2.666667 4.0
1 9.0 10.0 10.666667 12.0
2 17.0 18.0 18.666667 20.0
>>> df[cols].expanding(axis=1).mean().shift(axis=1)
A C D E
0 NaN 1.0 2.0 2.666667
1 NaN 9.0 10.0 10.666667
2 NaN 17.0 18.0 18.666667
>>> df[cols].expanding(axis=1).mean().shift(axis=1).fillna(0)
A C D E
0 0.0 1.0 2.0 2.666667
1 0.0 9.0 10.0 10.666667
2 0.0 17.0 18.0 18.666667