言归正传,我的输入(s1)和预期输出(df)如下:
#INPUT
s1 = pd.Series(['a', np.nan, 'b', 'c', np.nan, np.nan, 'd', np.nan]).rename('col1')
#EXPECTED-OUTPUT
s2 = pd.Series([1, 2, 3, 3, 4, 4, 5, 6]).rename('col2') # flag the transition null>notnull or vice-versa
s3 = pd.Series([0, 1, 0, 0, 2, 3, 0, 4]).rename('col3') # counter of the null values
df = pd.concat([s1, s2, s3], axis=1)
col1 col2 col3
0 a 1 0
1 NaN 2 1
2 b 3 0
3 c 3 0
4 NaN 4 2
5 NaN 4 3
6 d 5 0
7 NaN 6 4
我尝试了很多奇怪的 cumsum 和 mask 组合,但没有成功。可能那是因为我没有逻辑思维的基础。在开始构建为我提供系列的链条之前,我需要问自己哪些问题?
伙计们,任何帮助将不胜感激!
最佳答案
您可以使用isna
与 cumsum
和 where
对于“col3”。对于“col2”经典ne
+ shift
/cumsum
:
m = df['col1'].isna()
# if the flag is different from the previous one, increment
df['col2'] = m.ne(m.shift()).cumsum()
# increment on each True, mask the False
df['col3'] = m.cumsum().where(m, 0)
输出:
col1 col2 col3
0 a 1 0
1 NaN 2 1
2 b 3 0
3 c 3 0
4 NaN 4 2
5 NaN 4 3
6 d 5 0
7 NaN 6 4
中间体:
col1 col2 col3 m m.shift() m.ne(m.shift()) m.cumsum()
0 a 1 0 False NaN True 0
1 NaN 2 1 True False True 1
2 b 3 0 False True True 1
3 c 3 0 False False False 1
4 NaN 4 2 True False True 2
5 NaN 4 3 True True False 3
6 d 5 0 False True True 3
7 NaN 6 4 True False True 4
关于python - "cumsum"制作标志、计算计数和形成组的逻辑是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77059938/