【问题标题】:Pandas dataframe cumulative sum of column except last zero values除了最后一个零值外,Pandas 数据框的列累积总和
【发布时间】:2018-01-26 23:33:08
【问题描述】:

我想对 pandas 数据帧进行累积求和,而不会将总和结转到最后一个零值。例如,给一个数据框:

   A   B
1  1   2
2  5   0
3  10  0
4  10  1
5  0   1
6  5   2
7  0   0
8  0   0
9  0   0

仅索引1到6的累计和:

   A   B
1  1   2
2  6   2
3  16  2
4  26  3
5  26  4
6  31  6
7  0   0
8  0   0
9  0   0

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    如果不想将cumsum 用于所有列中的最后一个0 值:

    比较行号是否包含0,移位掩码并使用累积和。最后与最后一个值比较并过滤:

    a = df.ne(0).any(1).shift().cumsum()
    m = a != a.max()
    
    df[m] = df[m].cumsum()
    print (df)
        A  B
    1   1  2
    2   6  2
    3  16  2
    4  26  3
    5  26  4
    6  31  6
    7   0  0
    8   0  0
    9   0  0
    

    如果想分别处理每一列,类似的解决方案 - 只需省略 any

    print (df)
        A  B
    1   1  2
    2   5  0
    3  10  0
    4  10  1
    5   0  1
    6   5  0
    7   0  0
    8   0  0
    9   0  0
    
    a = df.ne(0).shift().cumsum()
    m = a != a.max()
    
    df[m] = df[m].cumsum()
    print (df)
        A  B
    1   1  2
    2   6  2
    3  16  2
    4  26  3
    5  26  4
    6  31  0
    7   0  0
    8   0  0
    9   0  0
    

    【讨论】:

      【解决方案2】:

      使用

      In [262]: s = df.ne(0).all(1)
      
      In [263]: l = s[s].index[-1]
      
      In [264]: df[:l] = df.cumsum()
      
      In [265]: df
      Out[265]:
          A  B
      1   1  2
      2   6  2
      3  16  2
      4  26  3
      5  26  4
      6  31  6
      7   0  0
      8   0  0
      9   0  0
      

      【讨论】:

        【解决方案3】:

        我会用last_valid_index

        v=df.replace(0,np.nan).apply(lambda x : x.last_valid_index())
        
        
        df[pd.DataFrame(df.index.values<=v.values[:,None],columns=df.index,index=df.columns).T].cumsum().fillna(0)
        
        
        Out[890]: 
              A    B
        1   1.0  2.0
        2   6.0  2.0
        3  16.0  2.0
        4  26.0  3.0
        5  26.0  4.0
        6  31.0  6.0
        7   0.0  0.0
        8   0.0  0.0
        9   0.0  0.0
        

        【讨论】:

          【解决方案4】:

          要跳过第一行 0, 0 之后的所有行,请使用 idxmax(0) 获取 df['A']df[B] 为 0 的第一个索引(按行)

          >>> m = ((df["A"]==0) & (df["B"]==0)).idxmax(0)
          >>> df[:m] = df[:m].cumsum()
          >>> df
              A  B
          0   1  2
          1   6  2
          2  16  2
          3  26  3
          4  26  4
          5  31  6
          6   0  0
          7   0  0
          8   0  0
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-06-29
            • 1970-01-01
            • 1970-01-01
            • 2019-02-15
            • 2021-10-28
            • 2017-05-15
            • 1970-01-01
            相关资源
            最近更新 更多