python - 2列上的Groupby加上String列上的过滤器
问题描述
样本 DF:
ID Name Price Condition Fit_Test
1 Apple 10 Good Super_Fit
2 Apple 10 OK Super_Fit
3 Apple 10 Bad Super_Fit
4 Orange 12 Good Not_Fit
5 Orange 12 OK Not_Fit
6 Banana 15 OK Medium_Fit
7 Banana 15 Bad Medium_Fit
8 Pineapple 25 OK Medium_Fit
9 Pineapple 25 OK Medium_Fit
10 Cherry 30 Bad Medium_Fit
预期的DF:
ID Name Price Condition Fit_Test
1 Apple 10 Good Super_Fit
2 Apple 10 OK Super_Fit
3 Apple 10 Bad Super_Fit
4 Orange 12 Good Not_Fit
6 Banana 15 OK Medium_Fit
8 Pineapple 25 OK Medium_Fit
9 Pineapple 25 OK Medium_Fit
10 Cherry 30 Bad Medium_Fit
问题陈述:
我想group-by
通过Name
然后Price
过滤基于Condition
.
如果存在 Good、Bad
Name
和Price
OK 的所有 3 个条件,则只保留 Good 一个,Fit_Test 不存在Super_Fit
如果存在 Good 和 OK 的 Name 和 Price 条件,则只保留 Good 一个(Id 4,5 只是预期的 ID 4)并且 Fit_Test 不是
Super_Fit
如果存在 Bad 和 OK 的一个
Name
和Price
条件,则只保留 OK 一个(Id 6,7 只是预期的 ID 6)并且 Fit_Test 不是Super_Fit
如果在 OK 和 OK 的一个
Name
和Price
条件内存在,Good 和 Good Exist 或只是 Bad 存在,那么不要做任何事情,然后只保留 OK 一个(Id 8,9,10 是 ID 8,9,10 在预期中)并且 Fit_Test 是不是Super_Fit
答案更新
- 测试的第一个答案和编辑适用于所有
df
没有Fit_Test
列条件的地方。在这个答案中,预期的 DF将没有第 2 行和第 3 行,如答案中所示 - 当您需要获取另一个列时, Edit for Update
Fit_Test
答案有效,并且仅当值不是时才有效Super_Fit
。
在这两种解决方案中,基于Condition
列的行过滤和 2 列的分组是相同的。
我在数字列上找到了带有 filter + group by 的东西,但在 String 列上没有找到。
解决方案
想法是 createset
用于比较:
a = df.join(df.groupby(['Price','Name'])['Condition'].apply(set).rename('m'),
on=['Price','Name'])['m']
print (a)
0 {Bad, Good, OK}
1 {Bad, Good, OK}
2 {Bad, Good, OK}
3 {Good, OK}
4 {Good, OK}
5 {Bad, OK}
6 {Bad, OK}
7 {OK}
8 {OK}
9 {Bad}
Name: m, dtype: object
m1 = (a == set({'Bad', 'Good', 'OK'})) | (a == set({'Good', 'OK'}))
m2 = a == set({'Bad', 'OK'})
#check if unique value - length of set is 1
m3 = a.str.len() == 1
m4 = df['Condition'] == 'Good'
m5 = df['Condition'] == 'OK'
df = df[(m1 & m4) | (m2 & m5) | m3]
print (df)
ID Name Price Condition
0 1 Apple 10 Good
3 4 Orange 12 Good
5 6 Banana 15 OK
7 8 Pineapple 25 OK
8 9 Pineapple 25 OK
9 10 Cherry 30 Bad
编辑测试:
对于测试是可能的使用assign
:
print (df.assign(sets=a, m1 = m1, m2=m2, m3=m3, m4=m4, m5=m5, m=m))
ID Name Price Condition sets m1 m2 m3 \
0 1 Apple 10 Good {Bad, Good, OK} True False False
1 2 Apple 10 OK {Bad, Good, OK} True False False
2 3 Apple 10 Bad {Bad, Good, OK} True False False
3 4 Orange 12 Good {Good, OK} True False False
4 5 Orange 12 OK {Good, OK} True False False
5 6 Banana 15 OK {Bad, OK} False True False
6 7 Banana 15 Bad {Bad, OK} False True False
7 8 Pineapple 25 OK {OK} False False True
8 9 Pineapple 25 OK {OK} False False True
9 10 Cherry 30 Bad {Bad} False False True
m4 m5 m
0 True False True
1 False True False
2 False False False
3 True False True
4 False True False
5 False True True
6 False False False
7 False True True
8 False True True
9 False False True
编辑更新:
对于新条件使用:
m6 = df['Fit_Test'] == 'Super_Fit'
df = df[((m1 & m4) | (m2 & m5) | m3) | m6]
print (df)
ID Name Price Condition Fit_Test
0 1 Apple 10 Good Super_Fit
1 2 Apple 10 OK Super_Fit
2 3 Apple 10 Bad Super_Fit
3 4 Orange 12 Good Not_Fit
5 6 Banana 15 OK Medium_Fit
7 8 Pineapple 25 OK Medium_Fit
8 9 Pineapple 25 OK Medium_Fit
9 10 Cherry 30 Bad Medium_Fit
推荐阅读
- javascript - connection.dispatcher.end() 正在断开机器人与语音通道的连接
- node.js - 为什么 node.js 在可视化代码中不起作用?
- prolog - CHR:如何在规则中调用 Prolog 代码
- wordpress - wp_get_nav_menu_items 多级子菜单
- javascript - jquery 仅扩展多个具有相似名称的 textarea 中的一个 textarea
- c# - 使用ajax将值从MVC视图传递到控制器
- google-apps-script - 将数据从一个工作簿过滤到另一个工作簿和 Google 表格中第二个工作簿中的工作表
- maven - Maven 编译器插件 - 将参数发送到 javac(类路径或 cp)
- ms-access - 如何关闭特定字段的正确大小写更正?
- python - 使用 tkinter 和 schedule 模块制作“屏幕储物柜”