我有一个看起来像这样的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']
对于列表中的每个元素,我想获得它前面的dataframe列的平均值加上它自己列中值的两倍。因此,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
我想知道是否有更多的Pythonic方法来完成相同的事情,而不是必须通过for循环?
答案 0 :(得分:1)
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
这会再现您预期的新列(并且A的值变为其原始值的两倍,这要归功于fillna将NaNs转换为0)。
我们可以看到这是一步一步来的:
从
开始>>> 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