【问题标题】:Conditional count of cumulative sum Dataframe - Loop through columns累积总和数据帧的条件计数 - 遍历列
【发布时间】:2019-05-05 23:17:15
【问题描述】:

我正在尝试根据每个值的符号在数据帧内通过重置来计算累积和。这个想法是对每一列分别进行相同的练习。

例如,假设我有以下数据框:

df = pd.DataFrame({'A': [1,1,1,-1,-1,1,1,1,1,-1,-1,-1],'B':[1,1,-1,-1,-1,1,1,1,-1,-1,-1,1]},index=[0, 1, 2, 3,4,5,6,7,8,9,10,11])

对于每一列,我想计算累积和,直到发现符号发生变化;在这种情况下,总和应重置为 1。对于上面的示例,我期待以下结果:

df1=pd.DataFrame({'A_cumcount':[1,2,3,1,2,1,2,3,4,1,2,3],'B_cumcount':[1,2,1,2,3,1,2,3,1,2,3,4],index=[0,1,2,3,4,5,6,7,8,9,10,11]})

此处已讨论过类似问题:Pandas: conditional rolling count

我已经尝试了以下代码:

nb_col=len(df.columns) #number of columns in dataframe


for i in range(0,int(nb_col)): #Loop through the number of columns in the dataframe

    name=df.columns[i] #read the column name
    name=name+'_cumcount' 


    #add column for the calculation
    df=df.reindex(columns=np.append(df.columns.values, [name])) 

    df=df[df.columns[nb_col+i]]=df.groupby((df[df.columns[i]] != df[df.columns[i]].shift(1)).cumsum()).cumcount()+1

我的问题是,有没有办法避免这种 for 循环?所以我可以避免每次都追加一个新列,使计算速度更快。谢谢

收到的答案(一切正常): 来自@nixon df.apply(lambda x: x.groupby(x.diff().ne(0).cumsum()).cumcount()+1).add_suffix('_cumcount')

来自@jezrael df1 = (df.apply(lambda x: x.groupby((x != x.shift()).cumsum()).cumcount() + 1).add_suffix('_cumcount'))

来自@Scott Boston:

df.apply(lambda x: x.groupby(x.diff().bfill().ne(0).cumsum()).cumcount() + 1)

【问题讨论】:

    标签: pandas loops dataframe cumsum


    【解决方案1】:

    我认为熊猫需要循环,例如apply:

    df1 = (df.apply(lambda x: x.groupby((x != x.shift()).cumsum()).cumcount() + 1)
             .add_suffix('_cumcount'))
    print (df1)
        A_cumcount  B_cumcount
    0            1           1
    1            2           2
    2            3           1
    3            1           2
    4            2           3
    5            1           1
    6            2           2
    7            3           3
    8            4           1
    9            1           2
    10           2           3
    11           3           1
    

    【讨论】:

    • @CTXR - 顺便说一句,不使用每列循环的原因是什么?大数据?
    • 没错,数据框很大!
    • @CTXR 您可以查看this 以获得其他更快的解决方案。
    • @CTXR - 如果我的回答有帮助,请不要忘记accept。谢谢。
    【解决方案2】:

    你可以试试这个:

    df.apply(lambda x: x.groupby(x.diff().bfill().ne(0).cumsum()).cumcount() + 1)
    

    输出:

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

    【讨论】:

      【解决方案3】:

      您可以通过执行x.diff().ne(0).cumsum() 并在组上使用cumcount 来按顺序发生更改的位置开始分组:

      df.apply(lambda x: x.groupby(x.diff().ne(0).cumsum())
                          .cumcount()+1).add_suffix('_cumcount')
      
              A_cumcount  B_cumcount
      0            1           1
      1            2           2
      2            3           1
      3            1           2
      4            2           3
      5            1           1
      6            2           2
      7            3           3
      8            4           1
      9            1           2
      10           2           3
      11           3           1
      

      【讨论】:

        猜你喜欢
        • 2021-06-09
        • 2019-07-03
        • 1970-01-01
        • 2017-11-28
        • 2021-12-07
        • 1970-01-01
        • 2021-04-23
        • 2022-08-18
        • 1970-01-01
        相关资源
        最近更新 更多