【问题标题】:How can I create a new column with a conditional cumulative sum using pandas?如何使用熊猫创建具有条件累积和的新列?
【发布时间】:2017-03-15 09:25:02
【问题描述】:

以下代码创建一个随机数据帧,其值为 -1、0 或 1:

df = pd.DataFrame(np.random.randint(-1,2,size=(100, 1)), columns=['val'])

print(df['val'].value_counts())

让我们看看它包含什么:

-1    36
 0    35
 1    29
Name: val, dtype: int64

然后,我尝试创建一个名为 mysum 的新列,其累积条件总和遵循以下规则:

  • 如果 val = 1 且 mysum >= 0,则 mysum = mysum + 1。
  • 如果 val = 1 且 mysum

  • 如果 val = -1 且 mysum

  • 如果 val = -1 且 mysum > 0,则 mysum = mysum - 2

  • 如果 val = 0 且 mysum

  • 如果 val = 0 且 mysum > 0,则 mysum = mysum - 1。

  • 如果 val = 0 且 mysum = 0,则 mysum = mysum。

所以恐怕没有这么简单:

df['mysum'] = df['val'].cumsum()

所以我尝试了以下方法:

df['mysum'] = 0

df['mysum'] = np.where((df['val'] == 1) & (df['mysum'].cumsum() >= 0), (df['mysum'].cumsum() + 1), df['mysum'].cumsum())
df['mysum'] = np.where((df['val'] == 1) & (df['mysum'].cumsum() < 0), (df['mysum'].cumsum() + 2), df['mysum'].cumsum())

df['mysum'] = np.where((df['val'] == -1) & (df['mysum'].cumsum() <= 0), (df['mysum'].cumsum() - 1), df['mysum'].cumsum())
df['mysum'] = np.where((df['val'] == -1) & (df['mysum'].cumsum() > 0), (df['mysum'].cumsum() - 2), df['mysum'].cumsum())

df['mysum'] = np.where((df['val'] == 0) & (df['mysum'].cumsum() > 0), (df['mysum'].cumsum() - 1), df['mysum'].cumsum())
df['mysum'] = np.where((df['val'] == 0) & (df['mysum'].cumsum() < 0), (df['mysum'].cumsum() + 1), df['mysum'].cumsum())


print(df['mysum'].value_counts())
print(df)

但是mysum的列没有累积!

这是一个你可以尝试的小提琴:https://repl.it/FaXZ/8

【问题讨论】:

  • 当 mysum 和 current val 都为 0 时 mysum 会发生什么?
  • 我没有意识到!我也添加了这个推理!谢谢
  • (如果这样发布循环解决方案是不可取的......)
  • @ntg 如何以非循环方式进行?
  • 好的,我的意思是明显的循环。检查 cumsum 的代码,我看到它是从以下位置添加到 generic.py 中的: cls.cumsum = _make_cum_function(cls, 'cumsum', name, name2, axis_descr, "cumulative sum",lambda y, axis: y.cumsum( axis), 0., np.nan), 类似cummmin等。可能会有一些 tweeks 以 pandas.Datafame 结束,通过在那里提供正确的函数来丰富 specialcumsum...

标签: python pandas numpy


【解决方案1】:

更有效的解决方案,另见generalized cumulative functions in NumPy/SciPy?

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randint(-1, 2, size=(100, 1)), columns=['val'])
def my_sum(acc,x):
    if x == 0 and acc < 0:
        return acc + 1
    if x == 1 and acc < 0:
        return acc + 2
    if x == -1 and acc <= 0:
        return acc - 1
    if x == 0 and acc > 0:
        return acc - 1
    if x == -1 and acc > 0:
        return acc - 2
    if x == 1 and acc >= 0:
        return acc + 1
    if x == 0 and acc == 0:
        return acc
u_my_sum = np.frompyfunc(my_sum, 2, 1)
df['mysum'] = u_my_sum.accumulate(df.val, dtype=np.object).astype(np.int64)
print(df)

【讨论】:

    【解决方案2】:

    也许存在更简洁的解决方案,但您可以遍历数据框并根据您的条件设置值。

    import numpy as np
    import pandas as pd
    
    df = pd.DataFrame(np.random.randint(-1, 2, size=(100, 1)), columns=['val'])
    
    df['mysum'] = 0
    
    for index, row in df.iterrows():
    
        # get the current value of mysum = mysum one row above current index
        mysum = df.get_value(index - 1, 1, takeable=True)
    
        # mysum at beginning is 0
        if index == 0:
            mysum = 0
    
        # set values at current index according to conditions
        if row[0] == 0 and mysum < 0:
            df.set_value(index, 1, mysum + 1, takeable=True)
        if row[0] == 1 and mysum < 0:
            df.set_value(index, 1, mysum + 2, takeable=True)
        if row[0] == -1 and mysum <= 0:
            df.set_value(index, 1, mysum - 1, takeable=True)
        if row[0] == 0 and mysum > 0:
            df.set_value(index, 1, mysum - 1, takeable=True)
        if row[0] == -1 and mysum > 0:
            df.set_value(index, 1, mysum - 2, takeable=True)
        if row[0] == 1 and mysum >= 0:
            df.set_value(index, 1, mysum + 1, takeable=True)
        if row[0] == 0 and mysum == 0:
            df.set_value(index, 1, mysum, takeable=True)
    
    print df
    

    【讨论】:

      猜你喜欢
      • 2019-10-11
      • 1970-01-01
      • 2021-11-01
      • 2019-01-09
      • 1970-01-01
      • 1970-01-01
      • 2022-11-16
      • 2019-07-26
      • 2017-05-15
      相关资源
      最近更新 更多