简体   繁体   English

将负行值与前几行相加 pandas

[英]Sum negative row values with previous rows pandas

I'm having trouble finding a good way to find all negative entries in a column and move them up the column, summing them up with the existing entry (ie subtracting the negative entry from the present entry) until all values are positive.我很难找到一种好方法来查找列中的所有负条目并将它们向上移动,将它们与现有条目相加(即从当前条目中减去负条目),直到所有值都是正数。

It is important that there are no negative values for the final dataframe & that all previously negative entries = 0. Also, the table is repeating, which means that I need to aggregate the results both based on the ID as well as on the entries (only do summations of entries of the same ID).重要的是最终 dataframe 没有负值,并且所有以前的负条目 = 0。此外,该表是重复的,这意味着我需要根据 ID 和条目汇总结果(仅对相同 ID 的条目进行求和)。

Based on an already presented table here:基于此处已提供的表格:

Present:当下:

ID ID Date日期 Entries参赛作品
1 1 2013 2013 100 100
1 1 2014 2014 0 0
1 1 2015 2015 60 60
1 1 2016 2016 -30 -30
1 1 2017 2017 0 0
1 1 2018 2018 50 50
1 1 2019 2019 0 0
1 1 2020 2020 -20 -20
2 2 2013 2013 100 100
2 2 2014 2014 0 0
2 2 2015 2015 60 60
2 2 2016 2016 -30 -30
2 2 2017 2017 0 0
2 2 2018 2018 50 50
2 2 2019 2019 0 0
2 2 2020 2020 -20 -20

Desired:期望:

ID ID Date日期 Entries参赛作品
1 1 2013 2013 100 100
1 1 2014 2014 0 0
1 1 2015 2015 30 30
1 1 2016 2016 0 0
1 1 2017 2017 0 0
1 1 2018 2018 30 30
1 1 2019 2019 0 0
1 1 2020 2020 0 0
2 2 2013 2013 100 100
2 2 2014 2014 0 0
2 2 2015 2015 30 30
2 2 2016 2016 0 0
2 2 2017 2017 0 0
2 2 2018 2018 30 30
2 2 2019 2019 0 0
2 2 2020 2020 0 0

You can try reverse cumsum after creating a group, then mask:您可以在创建组后尝试反向 cumsum,然后屏蔽:

s = df['Entries'].gt(0).cumsum()
u= df['Entries'][::-1].groupby(s).cumsum().mask(df['Entries'].le(0),0)
out = df.assign(New_Entries=u) # you can assign to the original column too.

print(out)
    ID  Date  Entries  New_Entries
0    1  2013      100          100
1    1  2014        0            0
2    1  2015       60           30
3    1  2016      -30            0
4    1  2017        0            0
5    1  2018       50           30
6    1  2019        0            0
7    1  2020      -20            0
8    2  2013      100          100
9    2  2014        0            0
10   2  2015       60           30
11   2  2016      -30            0
12   2  2017        0            0
13   2  2018       50           30
14   2  2019        0            0
15   2  2020      -20            0

A straight forward recursive function on the array of values值数组上的直接递归 function

df = pd.read_csv(io.StringIO("""ID  Date    Entries
1   2013    100
1   2014    0
1   2015    60
1   2016    -30
1   2017    0
1   2018    50
1   2019    0
1   2020    -20
2   2013    100
2   2014    0
2   2015    60
2   2016    -30
2   2017    0
2   2018    50
2   2019    0
2   2020    -20"""), sep="\t")

def shiftminus(a):
    touch=False
    for i,n in enumerate(a):
        if n<0 and i>0:
            a[i-1] += a[i]
            a[i] = 0
            touch=True
    if touch:
        a = shiftminus(a)
    return a

df["Entries"] = shiftminus(df["Entries"].values)


output output

 ID  Date  Entries
  1  2013      100
  1  2014        0
  1  2015       30
  1  2016        0
  1  2017        0
  1  2018       30
  1  2019        0
  1  2020        0
  2  2013      100
  2  2014        0
  2  2015       30
  2  2016        0
  2  2017        0
  2  2018       30
  2  2019        0
  2  2020        0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM