当na进入大熊猫栏时如何重置cumprod

时间:2019-08-26 15:01:33

标签: python pandas numpy

我在数据框中有一个两列,我想为这两个都计算cumprod,但是一旦看到该单元格中的na,该cumprod就需要重新启动

我已经尝试过直接使用cumprod,但是并没有得到正确的值,因为cumprod是连续的,并且在na出现时不会重新启动

这里是一个df

index     col1     col2
0          2         4
1          6         4
2          1         na
3          2         7
4          na        6
5          na        8
6          5         na
7          8         9 
8          3         2

这是我想要的输出:

index     col1     col2
0          2         4
1          12        16
2          12        na
3          24        7
4          na        42
5          na        336
6          5         na
7          40        9 
8          240       18

4 个答案:

答案 0 :(得分:3)

这是dict comprehension和默认构造函数的类似解决方案

pd.DataFrame({c: df[c].groupby(df[c].isna().cumsum()).cumprod() for c in df.columns})

     col1   col2
0    2.0    4.0
1   12.0   16.0
2   12.0    NaN
3   24.0    7.0
4    NaN   42.0
5    NaN  336.0
6    5.0    NaN
7   40.0    9.0
8  120.0   18.0

答案 1 :(得分:2)

这是一种解决方案,可在每列上运行,然后concats一起返回,因为每列的掩码都不同。


pd.concat(
  [df[col].groupby(df[col].isnull().cumsum()).cumprod() for col in df.columns], axis=1)

    col1   col2
0    2.0    4.0
1   12.0   16.0
2   12.0    NaN
3   24.0    7.0
4    NaN   42.0
5    NaN  336.0
6    5.0    NaN
7   40.0    9.0
8  120.0   18.0

一种稍微有效的方法是一次计算所有的石斑鱼面具并使用zip

m = df.isnull().cumsum()

pd.concat(
  [df[col].groupby(mask).cumprod() for col, mask in zip(df.columns, m.values.T)], axis=1)

答案 2 :(得分:1)

您可以将groupbyisnacumsum结合使用,以使用apply在各列中进行分组:

df.apply(lambda x: x.groupby(x.isna().cumsum()).cumprod())

输出:

        col1   col2
index              
0        2.0    4.0
1       12.0   16.0
2       12.0    NaN
3       24.0    7.0
4        NaN   42.0
5        NaN  336.0
6        5.0    NaN
7       40.0    9.0
8      120.0   18.0

答案 3 :(得分:0)

这是不需逐列操作的解决方案:

df = pd.DataFrame([[2,4], [6,4], [1,np.nan], [2,7], [np.nan,6], [np.nan,8], [5,np.nan], [8,9], [3,2]], 
                  columns=['col1', 'col2'])

df_cumprod = df.cumprod()
adjust_factor = df_cumprod.fillna(method='ffill').where(df_cumprod.isnull()).fillna(method='ffill').fillna(1)
print(df_cumprod / adjust_factor)

    col1   col2
0    2.0    4.0
1   12.0   16.0
2   12.0    NaN
3   24.0    7.0
4    NaN   42.0
5    NaN  336.0
6    5.0    NaN
7   40.0    9.0
8  120.0   18.0