根据列条件过滤几乎重复的数据

时间:2021-06-16 06:04:30

标签: python pandas dataframe

我有一个熊猫数据框,这是一个例子:

names  subject     date       marks
A        X      15-05-2021     10
A        X      22-05-2021     12
A        X      29-05-2021     11
A        Y      15-05-2021     15
A        Y      22-05-2021     10
B        P      22-05-2021     17
B        P      29-05-2021     16
B        Q      29-05-2021     14
B        R      22-05-2021     16

我需要过滤掉“29-05-2021”数据可用的所有姓名、日期和主题。

这就是我需要的:

names  subject     date       marks
A        X      15-05-2021     10
A        X      22-05-2021     12
A        X      29-05-2021     11
B        P      22-05-2021     17
B        P      29-05-2021     16
B        Q      29-05-2021     14

我已经想出了如何做到这一点,但我认为它可以改进。

这就是我现在所做的:

df = pd.read_excel("",name="sheet")
end_date = "29-05-2021"
end_date = pd.to_datetime(end_date)
mask = df["date"] == end_date
temp_df = df.loc[mask]
temp_df = temp_df[["names","subject"]]
result_df = pd.merge(df,temp_df, on = ["names","subject"],how="right"]

是否有改进的余地?

2 个答案:

答案 0 :(得分:1)

我认为为了提高性能,您的解决方案很好,使用 remove on 稍微简化(因为通过列名称的交集连接,此处为 name, subject)并且需要内部连接,这是默认设置,因此也应该省略:

end_date = "29-05-2021"

mask = df["date"] == pd.to_datetime(end_date)
result_df = pd.merge(df,df.loc[mask, ["names","subject"]])
print (result_df)
  names subject       date  marks
0     A       X 2021-05-15     10
1     A       X 2021-05-22     12
2     A       X 2021-05-29     11
3     B       P 2021-05-22     17
4     B       P 2021-05-29     16
5     B       Q 2021-05-29     14

如果 DataFrame 较大,则 GroupBy.transform 的替代解决方案会稍微慢一些:

end_date = "29-05-2021"

mask = df["date"] == pd.to_datetime(end_date)
df = df[df.assign(m = mask).groupby(['names','subject'])['m'].transform('any')]

答案 1 :(得分:1)

只需分组,并过滤​​任何符合您规格的日期。

df.groupby(['names','subject']).filter(lambda x:(x['date']=='29-05-2021').any())