首页 > 解决方案 > 基于数据框列结果,所有后续行都等于重复值,直到结果更改并出现新的重复值

问题描述

我的简化数据框如下:

df = pd.DataFrame()
df['A'] = ('IGNORE','IGNORE','IGNORE','YES','IGNORE','YES','YES','YES','IGNORE','IGNORE','IGNORE','YES','IGNORE','IGNORE','IGNORE','IGNORE','IGNORE','IGNORE','IGNORE','IGNORE','IGNORE', 'NO','IGNORE','IGNORE','IGNORE','IGNORE')

我需要反转数据框(我知道我可以通过 df = df[::-1] 来完成)然后按如下方式制作 B 列。

愿望输出如下:

df['B'] = ('GOOD','GOOD','GOOD','YES','IGNORE','YES','YES','YES','GOOD','GOOD','GOOD','YES','BAD','BAD','BAD','BAD','BAD','BAD','BAD','BAD','BAD', 'NO','IGNORE','IGNORE','IGNORE','IGNORE')

标签: pandasnumpydataframefor-loop

解决方案


想法是Series.map首先使用 dy 字典,回填缺失值,然后用fillnato替换最后一组Series,用于替换IGNORE连续值 - 2 或更多:

s = df['A'].map({'IGNORE': np.nan, 'YES':'GOOD', 'NO':'BAD'}).bfill().fillna(df['A'])
m1 = df.groupby(df['A'].ne(df['A'].shift()).cumsum())['A'].transform('size').ne(1)
m2 = df['A'].eq('IGNORE')

df['C'] = np.where(m1 & m2, s, df['A'])
print(df)
         A       B       C
0   IGNORE    GOOD    GOOD
1   IGNORE    GOOD    GOOD
2   IGNORE    GOOD    GOOD
3      YES     YES     YES
4   IGNORE  IGNORE  IGNORE
5      YES     YES     YES
6      YES     YES     YES
7      YES     YES     YES
8   IGNORE    GOOD    GOOD
9   IGNORE    GOOD    GOOD
10  IGNORE    GOOD    GOOD
11     YES     YES     YES
12  IGNORE     BAD     BAD
13  IGNORE     BAD     BAD
14  IGNORE     BAD     BAD
15  IGNORE     BAD     BAD
16  IGNORE     BAD     BAD
17  IGNORE     BAD     BAD
18  IGNORE     BAD     BAD
19  IGNORE     BAD     BAD
20  IGNORE     BAD     BAD
21      NO      NO      NO
22  IGNORE  IGNORE  IGNORE
23  IGNORE  IGNORE  IGNORE
24  IGNORE  IGNORE  IGNORE
25  IGNORE  IGNORE  IGNORE

推荐阅读