A B C
0 blue 14.5 14.0
1 blue 14.0 14.0
2 blue 13.5 14.0
3 blue 12.0 14.0
4 blue 10.5 14.0
5 green 20.0 19.0
6 green 19.0 19.0
7 green 18.5 19.0
8 green 18.0 19.0
9 green 17.5 19.0
10 green 16.0 19.0
我想创建一个新的df1
,其中包含下一个条件,每个 A组(“蓝色”和“绿色”):
如果组中不存在满足条件(B = C-1)的任何 B值,请进一步选择下一行这将是对应的。例如,在“蓝色组”中, B = C - 1 将 14.0 - 1 = 13.0 。由于不存在任何13.0
“蓝色组”,请选择df
中存在的下一行,即:
3 blue 12.0 14.0
df1应为:
A B C
1 blue 14.0 14.0
3 blue 12.0 14.0
6 green 19.0 19.0
8 green 18.0 19.0
我试过了:
df1 = df[(df["B"] == df["C"]) | (df["B"] == df["C"]-1)]
答案 0 :(得分:0)
使用:
D
,C
按计数减去GroupBy.cumcount
- 获取所有可能的值B == C-0,1,2,3...
groupby
按群组isin
进行过滤,删除列D
sort_values
A
和B
boolean indexing
df['D'] = df['C'].sub(df.groupby('A').cumcount())
df = df[df.groupby('A').apply(lambda x: x['B'].isin(x['D'])).values].drop('D',1)
df = df.sort_values(['A','B'], ascending=[True, False])
df = df[df.groupby('A').cumcount() < 2]
print (df)
A B C
1 blue 14.0 14.0
3 blue 12.0 14.0
6 green 19.0 19.0
8 green 18.0 19.0
答案 1 :(得分:0)
条件:
row where B = C - 1
if not exists B = C - 1, then row with largest B, such that B < C - 1
可以组合成1个条件:
row with largest B, such that B <= C - 1
如果您的数据是第一个条件,即所有组都存在row where B = C
,那么您可以像这样编写投影:
res = df[(df.B == df.C) | (df.B <= df.C - 1)].sort_values('B').groupby('A').tail(2)
# output:
A B C
3 blue 12.0 14.0
1 blue 14.0 14.0
8 green 18.0 19.0
6 green 19.0 19.0
如果第一个条件B = C
与某些组不匹配,则使用pd.concat结合两个单独的投影:
res = pd.concat([df[df.B == df.C],
df[df.B <= df.C - 1].sort_values('B').groupby('A').tail(1)])
# or you can split this long line into a couple of lines for better
# readibility
# p1 = df[df.B == df.C]
# p2 = df[df.B <= df.C - 1].sort_values('B').groupby('A').tail(1)
# res = pd.concat([p1, p2])
# output:
A B C
1 blue 14.0 14.0
6 green 19.0 19.0
3 blue 12.0 14.0
8 green 18.0 19.0
如您所见,对于第二个解决方案,行不会按您在问题中指定的顺序返回,因此如果您需要有序结果,则可能需要进一步的多列排序:
res.sort_values(['C', 'B'], ascending=[True, False])
答案 2 :(得分:0)
对于第二个条件:B = C - 1
,
B - C <= -1
然后在每个组中找到满足此条件的第一行的索引。
idx_cond = df.groupby("A").apply(
lambda x: x.where(x.B-x.C <= -1).first_valid_index())
# A
# blue 3
# green 8
# dtype: int64
pd.concat([df[df.B == df.C], df.loc[idx_cond]])