按小时和最大日期过滤数据框的行

6

在数据帧中,我想通过小时/键和等于最大日期来过滤某些“序列”的所有行。

我有一段可工作的代码,但想知道是否有更简洁或更优雅的方法来实现相同的功能?

df = pd.read_csv("./example.csv")
df["Date"] = pd.to_datetime(df["Date"])
Keys2Filter = (1, 2)
df

...
    Key Date    Value
0   1   2019-04-17 00:00:00 1
1   1   2019-04-17 01:00:00 2
2   1   2019-04-17 02:00:00 3
3   1   2019-04-17 00:00:00 4
4   1   2019-04-17 01:00:00 5
5   1   2019-04-17 00:00:00 7
6   2   2019-04-17 01:00:00 8
7   2   2019-04-17 02:00:00 9
8   2   2019-04-17 00:00:00 9
9   2   2019-04-17 01:00:00 9
10  3   2019-04-17 01:00:00 9
11  3   2019-04-17 01:00:00 9
...

if (len(Keys2Filter)):
    dfMax = df[df.Key.isin(Keys2Filter)]  
    dfMax = dfMax.groupby(by=["Key", dfMax.Date.dt.hour]).max()
    dfMax.index.names = ["Key", "Hour"]
    dfMax = dfMax.reset_index()
    df = df[~df.Key.isin(Keys2Filter)].append(dfMax.drop(columns=['Hour'])) 

df   

Key Date    Value
10  3   2019-04-17 01:00:00 9
11  3   2019-04-17 01:00:00 9
0   1   2019-04-17 00:00:00 7
1   1   2019-04-17 01:00:00 5
2   1   2019-04-17 02:00:00 3
3   2   2019-04-17 00:00:00 9
4   2   2019-04-17 01:00:00 9
5   2   2019-04-17 02:00:00 9
2个回答

3

解决方案很好,只需简化一下 - 布尔掩码应该缓存到变量 m 中,并使用 ~ 进行反转,另外还使用了双重 DataFrame.reset_index - 第一步是删除第二层级别,第二步是从索引中删除列:

m = df.Key.isin(Keys2Filter)
df = (df[~m].append(df[m].groupby(by=["Key", df.Date.dt.hour])
                         .max()
                         .reset_index(level=1, drop=True)
                         .reset_index()))

print (df)
    Key                Date  Value
10    3 2019-04-17 01:00:00      9
11    3 2019-04-17 01:00:00      9
0     1 2019-04-17 00:00:00      7
1     1 2019-04-17 01:00:00      5
2     1 2019-04-17 02:00:00      3
3     2 2019-04-17 00:00:00      9
4     2 2019-04-17 01:00:00      9
5     2 2019-04-17 02:00:00      9

3

根据我的理解,使用 transformisintransform将获取所有组中行的最大值,然后我们使用 isin,如果该值不在 Keys2Filter 中,则应选择,如果它在 Keys2Filter 中,将在 ~isin 下返回 False,则我们继续检查第二个条件,如果该行产生了组的最大值,则仍然选择它。

s=df.groupby([df.Key,df.Date.dt.strftime('%Y-%m-%d %H')])['Value'].transform('idxmax')
Keys2Filter = (1, 2)
df=df.loc[~df.Key.isin(Keys2Filter)|df.index.eq(s)].copy()#avoid the copy error 
df
Out[991]: 
    Key                Date  Value
2     1 2019-04-17 02:00:00      3
4     1 2019-04-17 01:00:00      5
5     1 2019-04-17 00:00:00      7
7     2 2019-04-17 02:00:00      9
8     2 2019-04-17 00:00:00      9
9     2 2019-04-17 01:00:00      9
10    3 2019-04-17 01:00:00      9
11    3 2019-04-17 01:00:00      9

注意,使用此方法将保持您的df的原始顺序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接