【发布时间】:2019-08-26 07:06:21
【问题描述】:
初始情况
考虑以下示例数据框:
df = pd.DataFrame({
'A': [3., 2., 1., np.nan],
'B': [7., np.nan, 1., 3.],
'C': [4., 5., 1., 2.],
'D': [1., 0., 2., 3.]
})
打印出来的样子是这样的:
A B C D
0 3.0 7.0 4.0 1.0
1 2.0 NaN 5.0 0.0
2 1.0 1.0 1.0 2.0
3 NaN 3.0 2.0 3.0
期望的结果
我现在想对该数据框的每一列执行以下操作:
- 计算列值的总和(忽略任何 NaN 值)。
- 如果总和超过 10.0,那么我想统一缩小列中的所有值,使新总和正好为 10.0(再次忽略任何 NaN 值)。
基本上我想获得一个如下所示的结果数据框:
A B C D
0 3.0 6.363636 3.333333 1.0
1 2.0 NaN 4.166667 0.0
2 1.0 0.909091 0.833333 2.0
3 NaN 2.727273 1.666667 3.0
到目前为止尝试过
下面的代码得到了想要的结果。
def helper_func(s):
if s.sum() > 10.:
return s * 10. / s.sum()
else:
return s
result_df = df.apply(helper_func)
但是,我觉得这段代码有点冗长且效率低下。根据我迄今为止对 pandas 的经验,我怀疑仍然可能有一个更加矢量化的解决方案。谁能帮我找到这个?
【问题讨论】:
-
首先,如果
s.sum > 10,您将计算s.sum()两次。将该值保存到变量中。虽然,为了解决您不太冗长的问题,您可以使用 lambda 函数df.apply(lambda s: s*10 / s.sum() if s.sum() > 10 else s)。