如何 drop_duplicate 每组使用不同的条件?
How to drop_duplicate using different condition per group?
我有 dataFrame,我需要根据另一列 'abs(col1 - col2)' 中的最小值删除每组的重复项 ('col1'),但我需要更改最后一组的条件,方法是采用'abs(col1 - col2)' 中对应于 'col1' 中最后一组的最大值,其中我按升序对 'col1' 进行了排序。 (表现为循环)
更新 1:
我需要动态分配最后一组。
例如,如果我有一个数据框
- 正在创建 DataFrame
df = pd.DataFrame( {'col0':['A','A','A','A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B','B','B','B'],'col1':[1,1,1,2,2,2,3,3,3,4,4,4,2,2,2,3,3,3,4,4,4,5,5,5], 'col2':[2,3,4,1,3,4,1,2,4,1,2,3,3,4,5,2,4,5,2,3,5,2,3,4]})
计算差异列(此列将用作条件)
df['abs(col1 - col2)']=abs(df['col1']-df['col2'])
- 原Df如下:
- 所需的 Df 应如下所示:
我的试用期:
df.sort_values(by=['col0','col1','abs(col1 - col2)','col2'],ascending=[True,True,True,False]).drop_duplicates(['col0','col1'])
结果如下:
如果这个特定的结果是你想要的,你可以拆分数据框并使用两个不同的规则,然后再次连接它们。例如:
import pandas as pd
df = pd.DataFrame( {'col1':[1,1,1,2,2,2,3,3,3,4,4,4], 'col2':[2,3,4,1,3,4,1,2,4,1,2,3]})
df['abs(col1 - col2)']=abs(df['col1']-df['col2'])
df = df.sort_values(by=['col1','abs(col1 - col2)','col2'],ascending=[True,True,False]).drop_duplicates('col1')
df1 = df.loc[df['col1'] != 4]
df2 = df.loc[df['col1'] == 4]
df2 = df2.sort_values(by=['col1','abs(col1 - col2)','col2'],ascending=[True,True,False])
df2Last = df2.tail(1)
df = pd.concat([df1, df2Last])
结果:
col1 col2 abs(col1 - col2)
1 2 1
2 3 1
3 4 1
4 1 3
已更新:
如果我没理解错的话,每次在 col1
上达到最大值时,您都需要不同的排序顺序。
- 提取排序不同的组:
df.groupby(['col0'], as_index=False)['col1'].max()
- 像您一样删除重复
df
- 仅删除在步骤 1 中找到的正确排序的组。您可以通过与原始
df
: 合并来获得这些组
pd.merge(df, col1_max_groups)
- 使用新值
更新去重DataFrame
完整示例:
col1_max_groups = df.groupby(['col0'], as_index=False)['col1'].max()
deduped = df.sort_values(['col0', 'col1', 'abs(col1 - col2)', 'col2'],
ascending=[True, True, True, False]) \
.drop_duplicates(['col0', 'col1']) \
.set_index(['col0', 'col1'])
update = pd.merge(df, col1_max_groups) \
.sort_values(['col0', 'col1', 'abs(col1 - col2)', 'col2'],
ascending=[True, True, False, False]) \
.drop_duplicates(['col0', 'col1'])
deduped.update(update.set_index(['col0', 'col1']))
deduped.reset_index()
# returns
# col0 col1 col2 abs(col1 - col2)
# A 1 2 1
# A 2 3 1
# A 3 4 1
# A 4 1 3
# B 2 3 1
# B 3 4 1
# B 4 5 1
# B 5 2 3
我有 dataFrame,我需要根据另一列 'abs(col1 - col2)' 中的最小值删除每组的重复项 ('col1'),但我需要更改最后一组的条件,方法是采用'abs(col1 - col2)' 中对应于 'col1' 中最后一组的最大值,其中我按升序对 'col1' 进行了排序。 (表现为循环)
更新 1:
我需要动态分配最后一组。
例如,如果我有一个数据框
- 正在创建 DataFrame
df = pd.DataFrame( {'col0':['A','A','A','A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B','B','B','B'],'col1':[1,1,1,2,2,2,3,3,3,4,4,4,2,2,2,3,3,3,4,4,4,5,5,5], 'col2':[2,3,4,1,3,4,1,2,4,1,2,3,3,4,5,2,4,5,2,3,5,2,3,4]})
计算差异列(此列将用作条件)
df['abs(col1 - col2)']=abs(df['col1']-df['col2'])
- 原Df如下:
- 所需的 Df 应如下所示:
我的试用期:
df.sort_values(by=['col0','col1','abs(col1 - col2)','col2'],ascending=[True,True,True,False]).drop_duplicates(['col0','col1'])
结果如下:
如果这个特定的结果是你想要的,你可以拆分数据框并使用两个不同的规则,然后再次连接它们。例如:
import pandas as pd
df = pd.DataFrame( {'col1':[1,1,1,2,2,2,3,3,3,4,4,4], 'col2':[2,3,4,1,3,4,1,2,4,1,2,3]})
df['abs(col1 - col2)']=abs(df['col1']-df['col2'])
df = df.sort_values(by=['col1','abs(col1 - col2)','col2'],ascending=[True,True,False]).drop_duplicates('col1')
df1 = df.loc[df['col1'] != 4]
df2 = df.loc[df['col1'] == 4]
df2 = df2.sort_values(by=['col1','abs(col1 - col2)','col2'],ascending=[True,True,False])
df2Last = df2.tail(1)
df = pd.concat([df1, df2Last])
结果:
col1 col2 abs(col1 - col2)
1 2 1
2 3 1
3 4 1
4 1 3
已更新:
如果我没理解错的话,每次在 col1
上达到最大值时,您都需要不同的排序顺序。
- 提取排序不同的组:
df.groupby(['col0'], as_index=False)['col1'].max()
- 像您一样删除重复
df
- 仅删除在步骤 1 中找到的正确排序的组。您可以通过与原始
df
: 合并来获得这些组
pd.merge(df, col1_max_groups)
- 使用新值 更新去重
DataFrame
完整示例:
col1_max_groups = df.groupby(['col0'], as_index=False)['col1'].max()
deduped = df.sort_values(['col0', 'col1', 'abs(col1 - col2)', 'col2'],
ascending=[True, True, True, False]) \
.drop_duplicates(['col0', 'col1']) \
.set_index(['col0', 'col1'])
update = pd.merge(df, col1_max_groups) \
.sort_values(['col0', 'col1', 'abs(col1 - col2)', 'col2'],
ascending=[True, True, False, False]) \
.drop_duplicates(['col0', 'col1'])
deduped.update(update.set_index(['col0', 'col1']))
deduped.reset_index()
# returns
# col0 col1 col2 abs(col1 - col2)
# A 1 2 1
# A 2 3 1
# A 3 4 1
# A 4 1 3
# B 2 3 1
# B 3 4 1
# B 4 5 1
# B 5 2 3