兰巴功能与其他

时间:2018-08-10 15:30:24

标签: python pandas if-statement dataframe lambda

我有一个看起来像这样的数据框:

request

我尝试运行:

A   B   C   D   SUM 
2   5   -4  12  15

要获取,如果单元格总数相同,则计算x / total:

df.apply((lambda x: x / x.sum() if x/x.sum() >= 0 else None), axis=1).fillna(0)

我得到:

A         B     C   D
2/15    5/15    0   12/15

我如何改善代码。

1 个答案:

答案 0 :(得分:0)

您正在混合pd.Series.applypd.DataFrame.apply。它们是不同的方法:一个工作在一系列上,并且对每个元素进行操作;另一个沿轴跨数据框运行。在后一种情况下,沿axis=1表示将每个 row 依次馈入该函数。

由于这两个apply方法(两个版本)都是薄薄的循环,因此在每次按列lambda调用之后,数据帧都会更改。因此,您将需要使用数据框的副本:

df2 = df.copy()

for col in df.columns[:-1]:
    df2[col] = df.iloc[:, :-1].apply(lambda x: x[col] / x.sum() if x[col]/x.sum() >= 0 \
                                     else None, axis=1).fillna(0)

print(df2)

          A         B  C    D  SUM
0  0.133333  0.333333  0  0.8   15

但是,这都是非常低效的。我们没有利用底层的NumPy数组。相反,您可以使用向量化操作:

res = df.iloc[:, :-1].div(df.iloc[:, :-1].sum(1), axis=0)
res.mask(res < 0, 0, inplace=True)

print(res)

          A         B    C    D
0  0.133333  0.333333  0.0  0.8