簡體   English   中英

Python pandas 按列分組並返回最近的模態值

[英]Python pandas group by column and return most recent modal value

我有以下兩個數據框:

  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

但是我無法弄清楚如何根據每個用戶的所有模態產品的最新日期僅返回一種模式。 請提出實現此目的的最佳方法。

嘗試:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM