大熊猫在grouby之后按日期时间过滤

Posted

技术标签:

【中文标题】大熊猫在grouby之后按日期时间过滤【英文标题】:pandas filter by datetime after grouby 【发布时间】:2021-02-10 22:54:58 【问题描述】:

在按特定列对数据框进行分组后,我想选择分组列的每个键的最后一个值之前的前六个月的日期。 例如,在这个数据框中

df = pd.DataFrame([
  'id': 'thing 1', 'date': '2016-01-01', 'quantity': 1 ,
  'id': 'thing 1', 'date': '2016-02-01', 'quantity': 1 ,
  'id': 'thing 1', 'date': '2016-09-01', 'quantity': 1 ,
  'id': 'thing 1', 'date': '2016-10-01', 'quantity': 1 ,
  'id': 'thing 2', 'date': '2017-01-01', 'quantity': 2 ,
  'id': 'thing 2', 'date': '2017-02-01', 'quantity': 2 ,
  'id': 'thing 2', 'date': '2017-02-11', 'quantity': 2 ,
  'id': 'thing 2', 'date': '2017-09-01', 'quantity': 2 ,
  'id': 'thing 2', 'date': '2017-10-01', 'quantity': 2 ,
])
df.date = pd.to_datetime(df.date, format="%Y-%m-%d")
df

我想选择thing 1的前2行和thing 2的前3行。

我可以找到每个id 的开始和结束日期:

df.groupby('id').date.max()-pd.DateOffset(years=1)
df.groupby('id').date.max()-pd.DateOffset(months=6)

但我找不到选择中间日期的方法。


我最好的(也是幼稚的)尝试如下:

df[(df.groupby('id').date>(df.groupby('id').date.max()-pd.DateOffset(years=1))) & (df.groupby('id').date<(df.groupby('id').date.max()-pd.DateOffset(months=6)))]

返回是可以理解的

TypeError:dtype=datetime64[ns] 和 SeriesGroupBy 之间的比较无效

【问题讨论】:

【参考方案1】:

您可以使用groupby.transform 并获取每行的最高日期。然后我们用pd.DateOffset减去6个月,最后用Series.lt与代表less than的每一行进行比较,与&lt;相同:

max_date = df.groupby('id')['date'].transform('max') - pd.DateOffset(months=6)
df[df['date'].lt(max_date)]
# or df[df['date'] < max_date]

输出

        id       date  quantity
0  thing 1 2016-01-01         1
1  thing 1 2016-02-01         1
4  thing 2 2017-01-01         2
5  thing 2 2017-02-01         2
6  thing 2 2017-02-11         2

【讨论】:

当我运行它时,我得到“dtype=float64 和 Timestamp 之间的无效比较”......但这似乎是正确的方法!一个警告是我还必须指定一个 min_date;我想我可以做到.gt(min_date)? 确保您的列都是datetime 类型。是的,首先制作一个 min_date 系列。如果您需要任何帮助,请告诉我。 我设法做到了,但用两行代码df=df[df['date'].lt(max_date)]' and df=df[df['date'].gt(min_date)]' 其中min_date = df.groupby('id')['date'].transform('max') - pd.DateOffset(years=1)。有没有一种行得通的?我在尝试df[(df['date'].lt(max_date)) and (df[df['date'].gt(min_date)])]的一些变体时遇到了一大堆错误@ Pandas 使用&amp; 作为逻辑运算符,所以这样做:df[df['date'].lt(max_date) &amp; df['date'].gt(min_date)] 啊!对...但现在我得到The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().【参考方案2】:

这可能是一种愚蠢的方法,但是...您可以根据现有日期在月份的 df 中添加一个新列。

df['MONTH'] = pd.DatetimeIndex(df['date']).month

它将在 1 月 1 日、2 月 2 日等

然后在前六个月过滤掉该列,其中 |表示或

df = df.loc[df['MONTH'] == 1]|[df['MONTH'] == 2]|[df['MONTH'] == 3]|[df['MONTH'] == 4]|[df['MONTH'] == 5]|[df['MONTH'] == 6]|

【讨论】:

一个简洁的方法:df.loc[df.date.dt.month.between(1,6)]

以上是关于大熊猫在grouby之后按日期时间过滤的主要内容,如果未能解决你的问题,请参考以下文章

按时间戳列过滤/选择熊猫数据帧的行

如何按当前日期之后的日期过滤?

根据日期列熊猫过滤数据框

当日期不唯一时,在熊猫中按日期分组后计数观察值

熊猫日期时间和日期时间日期时间之间的区别

带有熊猫的日期正则表达式过滤器不起作用