【问题标题】:Pandas cumulative sum on column with condition带有条件的列上的 Pandas 累积总和
【发布时间】:2015-04-02 19:54:18
【问题描述】:

我没有在其他地方找到答案,所以我需要问一下。可能是因为我不知道如何正确命名它。 (英语不是我的母语)

我有很大的日期时间数据框。时间在这里很重要。 df 中的一列具有值 [Nan, 1, -1]。当值发生变化时,我需要执行快速计算以重置累积和。

示例。

    Time                 sign    desire_value
2014-01-24 05:00:00      Nan     Nan 
2014-01-24 06:00:00      Nan     Nan
2014-01-24 07:00:00      Nan     Nan 
2014-01-24 08:00:00      1       1
2014-01-24 09:00:00      1       2
2014-01-24 10:00:00      1       3
2014-01-24 11:00:00      -1      1
2014-01-24 12:00:00      -1      2
2014-01-24 13:00:00      -1      3
2014-01-24 14:00:00      -1      4
2014-01-24 15:00:00      -1      5
2014-01-24 16:00:00      1       1
2014-01-24 17:00:00      1       2
2014-01-24 18:00:00      1       3
2014-01-24 19:00:00      -1      1
2014-01-24 20:00:00      -1      2  
2014-01-24 21:00:00      1       1
2014-01-24 22:00:00      1       2

我有使用函数的工作解决方案,但效率不高。

    df['sign_1'] = df['sign'].shift(1)

    for index, row in df.iterrows():
        if row.sign is None:
            df.loc[line, 'desire_value'] = None
        elif row.sign == row.sign_1:
            acc += 1
            df.loc[index, 'desire_value'] = acc
        else:
            acc = 1 
            df.loc[index, 'desire_value'] = acc

我找不到任何基于数组的方法。我发现在 Python 中高效迭代的最佳方法是使用 Cython,但是否有更多“Python”方法来解决这个问题?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    见最后一节here

    这是一个类似于 groupby 的迭代工具

    In [86]: v = df['value'].dropna()
    

    grouper 在组断点上分开; cumsum 使其具有单独的组

    In [87]: grouper = (v!=v.shift()).cumsum()
    
    In [88]: grouper
    Out[88]: 
    3     1
    4     1
    5     1
    6     2
    7     2
    8     2
    9     2
    10    2
    11    3
    12    3
    13    3
    14    4
    15    4
    16    5
    17    5
    Name: value, dtype: int64
    

    然后只是一个简单的 cumsum

    In [89]: df.groupby(grouper)['value'].cumsum()
    Out[89]: 
    0    NaN
    1    NaN
    2    NaN
    3      1
    4      2
    5      3
    6     -1
    7     -2
    8     -3
    9     -4
    10    -5
    11     1
    12     2
    13     3
    14    -1
    15    -2
    16     1
    17     2
    dtype: float64
    

    如果您确实想要绝对值,当然可以.abs() 以上。

    【讨论】:

    • 我认为他更多的是寻找cumcount() + 1(修补了 nans)而不是累积总和,尽管措辞如此。
    • @DSM 但不只是添加对 .abs() 的调用就可以满足 OP 的需求吗?
    • @EdChum:嗯。我想这里会的!我没有考虑到值仅限于 nan、-1 和 1 的后果。
    • 从我展示的内容到使用 .abs(...) 非常简单。我碰巧认为这更有用,但 OP 可以决定。
    • @Jeff,非常感谢你。使用 groupby 作为 itertool 不是很直观,但是非常高效。这个技巧将 65k 行的 df 计数从 45s 加快到 1.8s。 pandas 文档的这一部分不容易学习,但绝对值得。
    猜你喜欢
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 1970-01-01
    • 2017-05-16
    • 2019-02-15
    • 2021-07-20
    • 2020-08-04
    相关资源
    最近更新 更多