使用Python pandas按列进行分组并返回最近的众数值。

3
我有以下两个数据框:
  1. 一个包含所有用户ID的列表
  2. 另一个包含用户的网站活动。它具有UserID、ProductID和Datetime三列。
基本上,第二个数据框中的每一行都涉及到一个用户在给定日期时间查看产品页面的实例。
可以使用以下代码生成示例数据:
import pandas as pd
from datetime import datetime

df1 = pd.DataFrame({'UserID': [f'UID0{i}' for i in range(1, 10)]})

df2 = pd.DataFrame({'UserID': ['UID04', 'UID02', 'UID09', 'UID02', 'UID04', 'UID02', 'UID07', 'UID07', 'UID07', 'UID04', 'UID07', 'UID07'], 
                    'ProductID': ['P017', 'P008', 'P241', 'P340', 'P363', 'P340', 'P166', 'P042', 'P042', 'P042', 'P166', 'P017'], 
                    'Datetime': ['2017-09-10 15:48:09', '2018-05-26 04:52:35', '2017-09-29 18:26:42', '2017-03-06 15:04:58', '2017-09-07 18:44:24', '2016-03-11 05:06:32', '2016-04-11 18:22:19', '2017-09-04 04:44:23', '2018-12-19 07:34:06', '2018-04-09 04:39:55', '2017-04-11 18:22:19','2019-02-11 15:06:32']})
df2['Datetime'] = pd.to_datetime(df2['Datetime'], format='%Y-%m-%d %H:%M:%S')

我希望能够获取每个用户最常浏览的产品。如果存在多个众数,即拥有相同最高浏览量的多个产品,则必须考虑最近查看(基于 Datetime 列)的众数产品。如果用户没有浏览任何产品,则可以设置默认字符串,如“NoProduct”。
因此,对于给定的样本数据,预期输出应类似于以下内容:
UserID
UID01   NoProduct
UID02   P340
UID03   NoProduct
UID04   P042
UID05   NoProduct
UID06   NoProduct
UID07   P042
UID08   NoProduct
UID09   P241

我只能使用以下代码获取所有模式:

pd.merge(df1, df2.groupby(['UserID'])['ProductID'].agg(pd.Series.mode).to_frame().reset_index(), how='left').fillna('NoProduct')

输出结果为:

    UserID  ProductID
0   UID01   NoProduct
1   UID02   P340
2   UID03   NoProduct
3   UID04   [P017, P042, P363]
4   UID05   NoProduct
5   UID06   NoProduct
6   UID07   [P042, P166]
7   UID08   NoProduct
8   UID09   P241

但我无法弄清如何基于每个用户的所有模态产品中的最新日期仅返回单个模式。 请建议完成此操作的最佳方法。

1个回答

1

尝试:

df2["tmp"] = df2.groupby(["UserID", "ProductID"], as_index=False)["ProductID"].transform("count")

df2 = df2.sort_values(by=["tmp", "Datetime"], ascending=[False, False])

x = (
    df1.merge(
        df2.drop_duplicates(subset=["UserID"], keep="first"),
        on="UserID",
        how="left",
    )
    .drop(columns=["Datetime", "tmp"])
    .fillna("No Product")
)
print(x)

输出:

  UserID   ProductID
0  UID01  No Product
1  UID02        P340
2  UID03  No Product
3  UID04        P042
4  UID05  No Product
5  UID06  No Product
6  UID07        P042
7  UID08  No Product
8  UID09        P241

1
太好了。非常感谢!我也弄明白它是如何工作的了。 - Baheej Anwar

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