使用 pandas 按组筛选最近的事件
Filter for most recent event by group with pandas
我正在尝试过滤 pandas 数据框,以便能够获取数据框中每个帐号的最新数据点。
这是数据外观的示例。
我正在寻找包含产品和最近日期的帐户的一个实例的输出。
account_number product sale_date
0 123 rental 2021-12-01
1 423 rental 2021-10-01
2 513 sale 2021-11-02
3 123 sale 2022-01-01
4 513 sale 2021-11-30
我尝试使用 groupby
和 idxmax()
,但它不适用于日期。
而且我确实想将数据类型更改为远离日期时间。
data_grouped = data.groupby('account_number')['sale_date'].max().idxmax()
任何想法都会很棒。
关键字 'first' 有效吗?那将是:
data.groupby('account_number')['sale_date'].first()
我将更改我的答案以使用@Daniel Weigelbut 的答案...以及 ,您可以在其中应用 .nth(n)
来查找一般情况下的第 n 个值 ((-1 ) 最近的日期)。
new_data = data.groupby('account_number')['sale_date'].nth(-1)
我之前建议使用
创建排序的多索引
data.set_index(['account_number', 'sale_date'], inplace = True)
data_sorted = data.sort_index(level = [0, 1])
仍然有效,并且可能对任何更复杂的排序更有用。正如其他人所说,如果您这样排序,请确保您的日期字符串是日期时间对象。
sale_date
列似乎有字符串。如果将其转换为 datetime dtype,则可以使用 groupby
+ idxmax
:
df['sale_date'] = pd.to_datetime(df['sale_date'])
out = df.loc[df.groupby('account_number')['sale_date'].idxmax()]
输出:
account_number product sale_date
3 123 sale 2022-01-01
1 423 rental 2021-10-01
4 513 sale 2021-11-30
要保留子集数据框,请考虑按帐号和降序销售日期排序,然后调用 DataFrame.groupby().head
(如果在每个组的第一行不同于DataFrame.groupby().first
):
data_grouped = (
data.sort_values(
["account_number", "sale_date"], ascending=[True, False]
).reset_index(drop=True)
.groupby("account_number")
.head(1)
)
您需要 last
关键字以获取分组后的最新日期,如下所示:
df.groupby(by=["account_number"])["sale_date"].last()
将提供此输出:
account_number
123 2022-01-01
423 2021-10-01
513 2021-11-30
Name: sale_date, dtype: datetime64[ns]
不清楚您为什么要放弃使用 datetime dtype,但您需要它才能正确排序您要查找的值。考虑将此作为中间步骤,然后在处理后重新格式化该列。
我正在尝试过滤 pandas 数据框,以便能够获取数据框中每个帐号的最新数据点。 这是数据外观的示例。 我正在寻找包含产品和最近日期的帐户的一个实例的输出。
account_number product sale_date
0 123 rental 2021-12-01
1 423 rental 2021-10-01
2 513 sale 2021-11-02
3 123 sale 2022-01-01
4 513 sale 2021-11-30
我尝试使用 groupby
和 idxmax()
,但它不适用于日期。
而且我确实想将数据类型更改为远离日期时间。
data_grouped = data.groupby('account_number')['sale_date'].max().idxmax()
任何想法都会很棒。
关键字 'first' 有效吗?那将是:
data.groupby('account_number')['sale_date'].first()
我将更改我的答案以使用@Daniel Weigelbut 的答案...以及 .nth(n)
来查找一般情况下的第 n 个值 ((-1 ) 最近的日期)。
new_data = data.groupby('account_number')['sale_date'].nth(-1)
我之前建议使用
创建排序的多索引data.set_index(['account_number', 'sale_date'], inplace = True)
data_sorted = data.sort_index(level = [0, 1])
仍然有效,并且可能对任何更复杂的排序更有用。正如其他人所说,如果您这样排序,请确保您的日期字符串是日期时间对象。
sale_date
列似乎有字符串。如果将其转换为 datetime dtype,则可以使用 groupby
+ idxmax
:
df['sale_date'] = pd.to_datetime(df['sale_date'])
out = df.loc[df.groupby('account_number')['sale_date'].idxmax()]
输出:
account_number product sale_date
3 123 sale 2022-01-01
1 423 rental 2021-10-01
4 513 sale 2021-11-30
要保留子集数据框,请考虑按帐号和降序销售日期排序,然后调用 DataFrame.groupby().head
(如果在每个组的第一行不同于DataFrame.groupby().first
):
data_grouped = (
data.sort_values(
["account_number", "sale_date"], ascending=[True, False]
).reset_index(drop=True)
.groupby("account_number")
.head(1)
)
您需要 last
关键字以获取分组后的最新日期,如下所示:
df.groupby(by=["account_number"])["sale_date"].last()
将提供此输出:
account_number
123 2022-01-01
423 2021-10-01
513 2021-11-30
Name: sale_date, dtype: datetime64[ns]
不清楚您为什么要放弃使用 datetime dtype,但您需要它才能正确排序您要查找的值。考虑将此作为中间步骤,然后在处理后重新格式化该列。