熊猫按每个组内的日期范围过滤

时间:2021-03-24 16:41:26

标签: python pandas

我有一个喜欢的 df:

enter image description here

我必须通过从每个 ID 获得两周内的值来过滤我的 df 因此,对于每个 ID,我必须从第一次约会开始的接下来两周内预测,并且只保留这些记录。

输出:

enter image description here

我尝试为每个 ID 创建一个最小日期并使用以下代码尝试过滤:

df[df.date.between(df['min_date'],df['min_date']+pd.DateOffset(days=14))]

他们还有比这更有效的方法吗?因为这需要很多时间,因为我的数据框很大

2 个答案:

答案 0 :(得分:3)

设置

df = pd.DataFrame({
    'Id': np.repeat([2, 3, 4], [4, 3, 4]),
    'Date': ['12/31/2019', '1/1/2020', '1/5/2020', '1/20/2020',
             '1/5/2020', '1/10/2020', '1/30/2020', '2/2/2020',
             '2/4/2020', '2/10/2020', '2/25/2020'],
    'Value': [*'abcbdeefffg']
})

首先,使用 DateTimestamp 转换为 to_datetime

df['Date'] = pd.to_datetime(df['Date'])

concatgroupby 的理解

pd.concat([
    d[d.Date <= d.Date.min() + pd.offsets.Day(14)]
    for _, d in df.groupby('Id')
])

   Id       Date Value
0   2 2019-12-31     a
1   2 2020-01-01     b
2   2 2020-01-05     c
4   3 2020-01-05     d
5   3 2020-01-10     e
7   4 2020-02-02     f
8   4 2020-02-04     f
9   4 2020-02-10     f

布尔切片...也带有 groupby

df[df.Date <= df.Id.map(df.groupby('Id').Date.min() + pd.offsets.Day(14))]

   Id       Date Value
0   2 2019-12-31     a
1   2 2020-01-01     b
2   2 2020-01-05     c
4   3 2020-01-05     d
5   3 2020-01-10     e
7   4 2020-02-02     f
8   4 2020-02-04     f
9   4 2020-02-10     f

答案 1 :(得分:0)

我很难用 pandas.concat,所以你可以尝试使用 merge

# Convert Date to datetime
df['Date'] = pd.to_datetime(df['Date'], format='%m/%d/%Y')

# Get min Date for each Id and add two weeks (14 days)
s = df.groupby('Id')['Date'].min() + pd.offsets.Day(14)

# Merge df and s
df = df.merge(s, left_on='Id', right_index=True)

# Keep records where Date is less than the allowed limit
df = df.loc[df['Date_x'] <= df['Date_y'], ['Id','Date_x','Value']]

# Rename Date_x to Date (optional)
df.rename(columns={'Date_x':'Date'}, inplace=True)

结果是:

   Id       Date Value
0   2 2019-12-31     a
1   2 2020-01-01     b
2   2 2020-01-05     c
4   3 2020-01-05     d
5   3 2020-01-10     e
7   4 2020-02-02     f
8   4 2020-02-04     f
9   4 2020-02-10     f