根据列值有条件地保留重复项

时间:2019-09-13 08:11:01

标签: python pandas

我有以下数据框:

(Pdb++) df = pd.DataFrame([{'date': '2019-01-01', 'type': 'Q'},{'date': '2019-01-01', 'type': 'Y'},{'date': '2019-01-01', 'type': 'H'},{'date': '2019-01-02', 'type': 'Q'},{'date': '2019-01-02', 'type': 'Y'},{'date': '2019-01-03', 'type': 'H'},{'date': '2019-01-04', 'type': 'H'},{'date': '2019-01-04', 'type': 'Q'}]).set_index('date')
(Pdb++) df
           type
date           
2019-01-01    Q
2019-01-01    Y
2019-01-01    H
2019-01-02    Q
2019-01-02    Y
2019-01-03    H
2019-01-04    H
2019-01-04    Q

我想根据type列中重复行的值删除索引中的重复日期。

要求

  • 如果重复的日期包含QYH,请删除H
  • 如果重复的日期包含QY,则不删除任何内容。
  • 如果重复的日期包含QH,请删除H

一种简单的放置方法是:在一组重复的行中,删除H(如果有)。

预期产量

这样,以上代码的预期输出如下:(2019-01-01, H)(2019-01-04, H)被删除

           type
date           
2019-01-01    Q
2019-01-01    Y
2019-01-02    Q
2019-01-02    Y
2019-01-03    H
2019-01-04    Q

尝试

我似乎不太正确。我的两次尝试:

df.loc[(df['type'] == 'Y') | (df['type'] == 'Q') | ~df.index.duplicated(keep='last')]

df.loc[(df['type'] == 'Y') | (df['type'] == 'Q') | ~df.index.duplicated(keep='first')]

第一个未能删除(2019-01-01, H),第二个未能删除(2019-01-04, H)

我考虑过先对type列进行排序,以首先获取H值,然后再使用keep='first',但是出于某些无法解释的原因,这给了我一个错误:

(Pdb++) df.sort_values('type').loc[(df['type'] == 'Y') | (df['type'] == 'Q') | ~df.index.duplicated(keep='first')]
*** ValueError: cannot reindex from a duplicate axis

我在这里迷路了。有帮助吗?

2 个答案:

答案 0 :(得分:3)

将索引分组并取nunique,然后过滤大小大于1的条件,还检查type是否为H并取反:

s=df.groupby(df.index)['type'].transform('nunique')
df[~((s>1)&df.type.eq('H'))]

           type
date           
2019-01-01    Q
2019-01-01    Y
2019-01-02    Q
2019-01-02    Y
2019-01-03    H
2019-01-04    Q

答案 1 :(得分:1)

过滤掉所有H个值,如果不是仅包含值H的组:

m = df.type.eq('H')
df = df[~m | m.groupby(level=0).transform('all')]
print (df)
           type
date           
2019-01-01    Q
2019-01-01    Y
2019-01-02    Q
2019-01-02    Y
2019-01-03    H
2019-01-04    Q

详细信息

print (m.groupby(level=0).transform('all'))
date
2019-01-01    False
2019-01-01    False
2019-01-01    False
2019-01-02    False
2019-01-02    False
2019-01-03     True
2019-01-04    False
2019-01-04    False
Name: type, dtype: bool