如何在Pandas中将相似列合并为单个字典列
问题:将相似命名规则的DataFrame列转换为JSON格式列
给定如下示例DataFrame,其中以productlist开头的列遵循productlistN.属性名的命名规则,需要将这些列合并成一个JSON格式的productlist列:
import pandas as pd df = pd.DataFrame({'id' : 1, 'userName' : 'john', 'productlist0.name' : 'shoe', 'productlist0.price' : 45.89, 'productlist0.brand' : 'nike', 'productlist1.name' : 'jeans', 'productlist1.price' : 19.45, 'productlist1.brand' : 'howes', 'productlist2.name' : 'watch', 'productlist2.price' : 60.0, 'productlist2.brand' : 'fossil' }, index = [0])
期望转换后的结果如下:
df1 = pd.DataFrame( {'id' : 1, 'userName' : 'john', 'productlist' : '''[{'name' : 'shoe', 'price' : 45.89, 'brand' : 'nike'}, {'name' : 'jeans', 'price' : 19.45, 'brand' : 'howes'}, {'name' : 'watch', 'price' : 60.0, 'brand' : 'fossil'}]''' }, index = [0] )
用户尝试使用stack方法得到了如下中间结果,但不知道后续如何处理:
import re df.filter(regex = '^productlist').rename(columns = lambda x : re.sub(r'productlist\d\.', '', x)).stack().reset_index().\ groupby(['level_0', 'level_1'])[0].agg(dict) # 输出结果 level_0 level_1 0 brand {2: 'nike', 5: 'howes', 8: 'fossil'} name {0: 'shoe', 3: 'jeans', 6: 'watch'} price {1: 45.89, 4: 19.45, 7: 60.0} Name: 0, dtype: object
解决方案
可以通过以下步骤实现需求:
- 提取并拆分产品列:筛选出
productlist开头的列,将列名拆分为产品索引和属性名两部分。 - 重塑数据结构:将拆分后的列转换为多级索引,通过
stack和分组操作得到每个产品的属性集合。 - 转换为JSON格式:将属性字典列表转为JSON字符串,最后与原DataFrame的非产品列合并。
完整代码如下:
import pandas as pd import json # 原始数据 df = pd.DataFrame({'id' : 1, 'userName' : 'john', 'productlist0.name' : 'shoe', 'productlist0.price' : 45.89, 'productlist0.brand' : 'nike', 'productlist1.name' : 'jeans', 'productlist1.price' : 19.45, 'productlist1.brand' : 'howes', 'productlist2.name' : 'watch', 'productlist2.price' : 60.0, 'productlist2.brand' : 'fossil' }, index = [0]) # 筛选产品相关列,拆分列名为(产品索引, 属性)的多级结构 product_cols = df.filter(regex='^productlist') product_cols.columns = product_cols.columns.str.extract(r'productlist(\d+)\.(.*)', expand=True) # 重塑结构:将产品索引转为行,按原行分组生成每个产品的属性字典列表 product_list = product_cols.stack(level=0).groupby(level=0).apply(lambda x: x.to_dict('records')).reset_index(name='productlist') # 合并原数据的非产品列和新生成的productlist列 result = pd.concat([df.drop(columns=product_cols.columns.get_level_values(0)), product_list['productlist']], axis=1) # 可选:将字典列表转为标准JSON字符串(如果需要字符串格式而非Python对象) result['productlist'] = result['productlist'].apply(json.dumps) print(result)
代码说明:
- 列名拆分:用
str.extract把productlistN.属性拆分为(N, 属性)的多级列名,为后续分组操作铺路。 - 结构重塑:
stack(level=0)将产品索引转为行索引,再按原数据的行索引分组,用to_dict('records')直接生成每个产品的属性字典列表。 - 列合并:把原数据的非产品列(
id、userName)和新的productlist列拼接,得到最终结果。 - JSON转换:如果需要字符串格式的JSON而非Python列表对象,用
json.dumps转换即可。
运行后输出结果与预期一致:
id userName productlist 0 1 john [{"name": "shoe", "price": 45.89, "brand": "nike"}, {"name": "jeans", "price": 19.45, "brand": "howes"}, {"name": "watch", "price": 60.0, "brand": "fossil"}]
内容的提问来源于stack exchange,提问作者Karthik S
相关产品推荐
相关产品推荐

