python - 从字典列表的 JSON 列中获取 'history' 项

标签 python pandas

我有一个具有以下格式(简化)的数据框:

userid 是一个字符串,purchased_items 是一个 JSON 字符串(字典列表的格式)。

<表类=“s-表”> <标题> 用户ID 已购买的商品 <正文> U123 [{"itemid":"I456","t":1649722121709}, {"itemid":"I789","t":1649722118064}, {itemid:"I123","t":1649722034610}] U456 [{"itemid":"I123","t":1649721903646}]

其中itemid是用户购买的商品,“t”是发生的时间戳(字典按照时间戳降序排序,因此最早的时间戳排在前面。)。

我想要什么: 对于每个用户和时间戳,获取当前时间戳之前和期间购买的所有商品的列表

<表类=“s-表”> <标题> 用户ID 时间戳 以前购买的商品 <正文> U123 1649722121709 I456 U123 1649722118064 I456 I789 U123 1649722034610 I456 I789 I123 U456 1649721903646 I123

编辑-我尝试过的 因此,我尝试首先按行分解问题,并计划从下面的代码创建一个函数并将其应用于每一行。

visits = df[df['userid']=='U123']['purchased_items'].values[0] #visits is of type list
dict_of_rows = {}
history = []
for i in visits:
  if i is not None:
    obj = json.loads(i)
    dict_of_rows['timestamp'] = obj['t']
    dict_of_rows['history'] = history
    history.append(obj['itemid'])

我得到了什么:

dict_of_rows
{'history': ['I456', 'I789', 'I123'],
 'timestamp': 1649722034610}

这只给了我想要的一行(输出表的第 3 行),我希望能够获得输出表的前 3 行。

我的计划是使用这个行字典来构建另一个提供输出表的数据框。

最佳答案

您可以使用 explodepd.json_normalize 将字典 purchased_items 列的原始列表转换为多列。

df = df.explode('purchased_items').reset_index()
df = pd.concat([df['userid'], pd.json_normalize(df['purchased_items'])], axis=1).sort_values(['userid', 't'], ascending=[True, False])
print(df)

  userid itemid              t
0   U123   I456  1649722121709
1   U123   I789  1649722118064
2   U123   I123  1649722034610
3   U456   I123  1649721903646

然后,您可以按 userid 列进行分组,然后通过在组行上apply 将当前行的前一行连接到每个组中。

out = df.groupby('userid').apply(lambda group: group.apply(lambda row: ' '.join(group.reset_index().loc[:row.name, 'itemid']).strip(), axis=1)).reset_index(drop=True)
print(out)

0              I456
1         I456 I789
2    I456 I789 I123
3              I123

最后,将返回的Series添加到原始数据框中

df['previously purchased items'] = out
df = df.drop(columns=['itemid']).rename(columns={'t': 'timestamp'})
print(df_)

  userid      timestamp previously purchased items
0   U123  1649722121709                       I456
1   U123  1649722118064                  I456 I789
2   U123  1649722034610             I456 I789 I123
3   U456  1649721903646                       I123

如果您想排除当前购买的商品,可以将groupby更改为以下

out = df.groupby('userid').apply(lambda group: group.assign(temp=group['itemid'].shift(fill_value='')).pipe(lambda g: g.reset_index().apply(lambda row: ' '.join(g.loc[:row.name, 'temp']).strip(), axis=1))).reset_index(drop=True)
print(df)

  userid      timestamp previously purchased items
0   U123  1649722121709
1   U123  1649722118064                       I456
2   U123  1649722034610                  I456 I789
3   U456  1649721903646

关于python - 从字典列表的 JSON 列中获取 'history' 项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71907333/

相关文章:

python - 在 pandas 中创建列配对

python - 基于字符,如何在新行中分隔 pandas 数据帧的每个单元格?

python - 将xlrd安装到python3.6中

python - 从 mysqldb 查询中获取原始十进制值

javascript - Python 与 JavaScript 中的 HMAC SHA256

python - 使用一组字符串对 pandas 系列进行索引会删除该系列中的原始数据

python - 读取 excel 文件时将转换器应用于所有列,Python 3.6

python - 我怎样才能用空格分割这个数据框?

python-2.7 - 使用pandas inplace关键字参数的准则

python - 如何映射到 Pandas 列表列中的值