如果重复计数大于1且符合条件,则Pandas框架将删除重复项

von4xj4u  于 2023-11-15  发布在  其他
关注(0)|答案(2)|浏览(159)

我有这样的数据:

data = [['ABC','A','Good Value'], ['DEF','V','Good Value'], ['ABC','A','Unclear Value'], ['XYZ','B','Good Value'], ['LMN','N','Unclear Value'], ['JKL','M','Best Value'], ['ABC','A','Better Value'], ['JKL','M','Good Value']] 

df = pd.DataFrame(data, columns=['Name', 'Class', 'Value'])

字符串
| 数量|名称|类|值|
| --|--|--|--|
| 1 |ABC|一|好的价值|
| 2 |DEF| V|好的价值|
| 3 |ABC|一|值不明确|
| 4 |XYZ| B|好的价值|
| 5 |LMN| N|值不明确|
| 6 |JKL| M|最佳价值|
| 7 |ABC|一|更好的价值|
| 8 |JKL| M|好的价值|
我希望仅当存在重复项时才删除列['Name','Class']上的重复项。如果存在['Name','Class']组合的单个条目,则保留该条目。此外,当列['Name','Class']上存在重复项时,仅当值为“Unclear Value”时才删除该条目。
因此,预期的输出是删除行#3,保留#1和#7。保留#6和#8,因为它们都不是“Unlcear值”。保留#5,因为它是唯一一个具有名称LMN和类N的行,所以即使它具有Unclear值,也应该保留它。
到目前为止,我得到的是一个所有可能值的优先级列表。如['Good value','Best Value','Better Value','Unclear Value'],其中Unclear值是列表中的最后一个。然后我将Value列转换为Pandas Categorical

df.Value = pd.Categorical(df.Value, categories=['Good Value', 'Best Value', 'Better Value', 'Unclear Value'],ordered=True)


然后这样做:

df.sort_values('Value').groupby(['Name', 'Class']).first()


这个方法遇到的问题是#6和#8中的一个被删除。另外,3行#1、#3、#7中只有一行被保留,而我只希望#3被删除。
另一件事是,这个优先级列表实际上只是为了让我保留一个Good值而不是Unclear值。实际上并没有提供这样的优先级列表。我自己定义了这个列表,所以我可以在最低优先级保留Unclear值,这样它可能会被丢弃。我宁愿根本没有优先级列表。
目前我能想到的唯一方法是进行分组并获得值的唯一计数。然后在计数> 1的组上迭代,并为每个这样的组删除值为“Unclear Value”的行。但我不想在数据上迭代,因此寻找更复杂的解决方案。

polkgigr

polkgigr1#

您可以使用两个掩码的布尔索引:

# is the Name/Class combination duplicated?
m1 = df[['Name', 'Class']].duplicated(keep=False)
# is the Value "Unclear Value"?
m2 = df['Value'].eq('Unclear Value')

# drop if both conditions are met
out = df[~(m1&m2)]

字符串
输出量:

Name Class          Value
0  ABC     A     Good Value
1  DEF     V     Good Value
3  XYZ     B     Good Value
4  LMN     N  Unclear Value
5  JKL     M     Best Value
6  ABC     A   Better Value
7  JKL     M     Good Value


中间体:

Name Class          Value     m1     m2  m1&m2  ~(m1&m2)
0  ABC     A     Good Value   True  False  False      True
1  DEF     V     Good Value  False  False  False      True
2  ABC     A  Unclear Value   True   True   True     False
3  XYZ     B     Good Value  False  False  False      True
4  LMN     N  Unclear Value  False   True  False      True
5  JKL     M     Best Value   True  False  False      True
6  ABC     A   Better Value   True  False  False      True
7  JKL     M     Good Value   True  False  False      True

c8ib6hqw

c8ib6hqw2#

与@mozway对Categorical的想法相同的逻辑:

cat = pd.CategoricalDtype(['Good Value', 'Best Value', 'Better Value',
                           'Unclear Value'], ordered=True)

cnt = (df.astype({'Value': cat}).sort_values('Value')
         .groupby(['Name', 'Class']).cumcount())

out = df[~(df['Value'].eq('Unclear Value') & cnt.gt(1))]

字符串
输出量:

>>> out
  Name Class          Value  count
1  ABC     A     Good Value      0
2  DEF     V     Good Value      0
4  XYZ     B     Good Value      0
5  LMN     N  Unclear Value      0
6  JKL     M     Best Value      1
7  ABC     A   Better Value      1
8  JKL     M     Good Value      0

相关问题