【发布时间】:2021-12-26 04:36:40
【问题描述】:
我有以下数据框:
id outcome
0 3 no
1 3 no
2 3 no
3 3 yes
4 3 no
5 5 no
6 5 no
7 5 yes
8 5 yes
9 6 no
10 6 no
11 6 yes
12 6 yes
13 6 yes
14 6 yes
15 6 yes
16 6 no
17 6 no
18 6 no
19 7 no
20 7 no
21 7 yes
22 7 yes
23 7 no
24 7 no
25 7 no
26 7 yes
它是根据 id 分组的。
我需要满足几个条件。
如果后面的行具有相同的结果,我需要删除当前行。
如果一行是“是”,那么下一行必须是第一个“否”。
我还必须在“是”序列中包含最后一个“是”行。
此外,我还希望将最后一个“否”保持在“是”之上(因此在“是”之上可能有 2 个“否”值:基本上在一排“否”中,第一个和最后一个“否”)。
然后我需要删除最后一行的任何“是”行。
最后,如果一个“id”列只有一个“否”行,那么它也必须被删除。
这应该是输出。
id outcome
2 3 no
3 3 yes
4 3 no
10 6 no
15 6 yes
16 6 no
20 7 no
22 7 yes
23 7 no
25 7 no
26 7 yes
我目前正在这样做:
df = pd.DataFrame(data={'id':[3,3,3,3,3,5,5,5,5,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7],
'outcome': ['no','no','no','yes','no','no','no','yes','yes','no','no','yes','yes','yes','yes','yes','no','no','no', 'no', 'yes', 'no', 'no', 'yes']})
# part 1
g = df.groupby('id')['outcome']
m1 = g.shift().eq('yes') | g.shift(-1).eq('yes')
df = df[m1 & df.outcome.ne('yes') | (df.outcome.eq('yes') & g.shift().ne('yes') ) ]
# part 2
# The following removes any last rows that are a 'yes' per id
m2 = df.groupby(['id'])['outcome'].tail(1) != 'no'
df = df.drop(m2[m2].index)
#part 3
# The following removes any id counts that are one, as the last row 'yes' values should be removed, this would mean only 'no' rows are leftover
df_count = df.groupby(['id'])['outcome'].count().to_frame('count').reset_index()
df = pd.merge(df, df_count[['id','count']] , on=['id'], how='inner')
df = df.drop((df[df.count == 1].index))
但是,第 1 部分保留了第一个“是”值行,而不是我需要的最后一个“是”。
我也不确定第 2 部分和第 3 部分是否过于冗长,以及我是否可以做一些更精简的事情来满足上述所有条件。
【问题讨论】:
标签: python pandas dataframe numpy time-series