首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在有条件的组中选择行

在有条件的组中选择行
EN

Stack Overflow用户
提问于 2018-03-04 14:56:08
回答 3查看 1.3K关注 0票数 2
代码语言:javascript
复制
        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

我想为每个A组(“蓝色”和“绿色”)创建一个新的带有下一个条件的df1

  • 选择B=C的行和B=C1的行
  • 如果它在满足条件的组中不存在任何B值(B =C1),则选择下一行以对应。例如,在“蓝色组”中,B=C-1将是14.0-1= 13.0。由于它不存在任何13.0“蓝色组”,请选择df中存在的下一行,即: 3 blue 12.0 14.0

df1应该是:

代码语言:javascript
复制
       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

我试过:

代码语言:javascript
复制
df1 = df[(df["B"] == df["C"]) | (df["B"] == df["C"]-1)]
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-04 22:16:52

对于第二个条件: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#蓝色3#绿色8# dtype: int64 pd.concat([dfdf.B == df.C,df.locidx_cond])
票数 0
EN

Stack Overflow用户

发布于 2018-03-04 19:42:47

条件:

  • row where B = C - 1
  • if not exists B = C - 1, then row with largest B, such that B < C - 1

可以合并为一个条件:

代码语言:javascript
复制
row with largest B, such that B <= C - 1

如果您的数据是第一个条件,即所有组都存在row where B = C,那么您可以这样编写投影:

代码语言:javascript
复制
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合并两个单独的投影:

代码语言:javascript
复制
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

如您所见,对于第二个解决方案,行不会按照问题中指定的顺序返回,因此,如果需要排序结果,则可能需要进一步的多列排序:

代码语言:javascript
复制
res.sort_values(['C', 'B'], ascending=[True, False])
票数 1
EN

Stack Overflow用户

发布于 2018-03-04 16:16:57

使用:

  • 首先创建助手列D,并通过GroupBy.cumcount通过计数器减去C -获取所有可能的值B == C-0,1,2,3...
  • 使用isin对每个组进行groupby筛选,删除列D
  • 如有必要按ABsort_values进行排序
  • boolean indexing按计数器过滤每组前2行
代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49096679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档