pandas 如何用以前的值填充列直到满足条件

k3bvogb1  于 2023-09-29  发布在  其他
关注(0)|答案(3)|浏览(101)

背景我有一个由数百万个值组成的大型数据框。它看起来像下面

  1. import pandas as pd
  2. df = pd.DataFrame({'level':[1,1,1,2,3,2,2,1,2,1,2,3,3,4,5,2,3,4,5,1,1],
  3. 'type':['','','com','','','','','','','','com','','','','','','','com','','','']})
  4. print(df)
  5. level type
  6. 0 1
  7. 1 1
  8. 2 1 com
  9. 3 2
  10. 4 3
  11. 5 2
  12. 6 2
  13. 7 1
  14. 8 2
  15. 9 1
  16. 10 2 com
  17. 11 3
  18. 12 3
  19. 13 4
  20. 14 5
  21. 15 2
  22. 16 3
  23. 17 4 com
  24. 18 5
  25. 19 1
  26. 20 1

我想把我的画框洗成这样。将type=com后的前一个值填入空白处,直到level等于/小于带有com的起始行的level。有什么想法吗?非常感谢。

  1. level type type_new
  2. 0 1
  3. 1 1
  4. 2 1 com com
  5. 3 2 com
  6. 4 3 com
  7. 5 2 com
  8. 6 2 com
  9. 7 1
  10. 8 2
  11. 9 1
  12. 10 2 com com
  13. 11 3 com
  14. 12 3 com
  15. 13 4 com
  16. 14 5 com
  17. 15 2
  18. 16 3
  19. 17 4 com com
  20. 18 5 com
  21. 19 1
  22. 20 1
wn9m85ua

wn9m85ua1#

一个选择:

  1. # identify non-empty
  2. m = df['type'].ne('')
  3. # mask and forward fill
  4. s = df['level'].where(m).ffill()
  5. # set up "com" on values above threshold
  6. df['type_new'] = ''
  7. df.loc[(m|s.lt(df['level'])).groupby(m.cumsum()).cummin(), 'type_new'] = 'com'

另一种方法:

  1. # identify non-empty
  2. m = df['type'].ne('')
  3. # forward-fill
  4. tmp = df.where(m).ffill()
  5. # identify values that return to initial value
  6. m2 = df['level'].mask(m).groupby(m.cumsum()).cummin().gt(tmp['level'])
  7. # assign
  8. df['type_new'] = df['type'].mask(m2).ffill()

输出量:

  1. level type type_new
  2. 0 1
  3. 1 1
  4. 2 1 com com
  5. 3 2 com
  6. 4 3 com
  7. 5 2 com
  8. 6 2 com
  9. 7 1
  10. 8 2
  11. 9 1
  12. 10 2 com com
  13. 11 3 com
  14. 12 3 com
  15. 13 4 com
  16. 14 5 com
  17. 15 2
  18. 16 3
  19. 17 4 com com
  20. 18 5 com
  21. 19 1
  22. 20 1
展开查看全部
iswrvxsc

iswrvxsc2#

  1. cond1 = df['type'].eq('com')
  2. grp = cond1.cumsum()
  3. cond2 = df['level'] <= df.groupby(grp)['level'].transform('first')
  4. df['type_new'] = df['type'].mask(grp.gt(0) & cond2.groupby(grp).cumsum().eq(1), 'com')

df

  1. level type type_new
  2. 0 1
  3. 1 1
  4. 2 1 com com
  5. 3 2 com
  6. 4 3 com
  7. 5 2 com
  8. 6 2 com
  9. 7 1
  10. 8 2
  11. 9 1
  12. 10 2 com com
  13. 11 3 com
  14. 12 3 com
  15. 13 4 com
  16. 14 5 com
  17. 15 2
  18. 16 3
  19. 17 4 com com
  20. 18 5 com
  21. 19 1
  22. 20 1
展开查看全部
v09wglhw

v09wglhw3#

用途:

  1. #forward fill type
  2. s = df['type'].replace('', np.nan).ffill()
  3. #test com
  4. m = df['type'].eq('com')
  5. #test if level is less or equal by forward filled first value if com
  6. mask = df['level'].le(df['level'].where(m).ffill()) & ~m
  7. #per groups by com set empty string
  8. df['type_new'] = s.mask(mask.groupby(m.cumsum()).cummax(), '').fillna('')
  1. print(df)
  2. level type type_new
  3. 0 1
  4. 1 1
  5. 2 1 com com
  6. 3 2 com
  7. 4 3 com
  8. 5 2 com
  9. 6 2 com
  10. 7 1
  11. 8 2
  12. 9 1
  13. 10 2 com com
  14. 11 3 com
  15. 12 3 com
  16. 13 4 com
  17. 14 5 com
  18. 15 2
  19. 16 3
  20. 17 4 com com
  21. 18 5 com
  22. 19 1
  23. 20 1
展开查看全部

相关问题