我有一个具有以下格式(简化)的数据框:
userid
是一个字符串,purchased_items
是一个 JSON 字符串(字典列表的格式)。
其中itemid是用户购买的商品,“t”是发生的时间戳(字典按照时间戳降序排序,因此最早的时间戳排在前面。)。
我想要什么: 对于每个用户和时间戳,获取当前时间戳之前和期间购买的所有商品的列表
编辑-我尝试过的 因此,我尝试首先按行分解问题,并计划从下面的代码创建一个函数并将其应用于每一行。
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 行。
我的计划是使用这个行字典来构建另一个提供输出表的数据框。
最佳答案
您可以使用 explode
和 pd.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/