使用Python将竖线分隔CSV转换为含多类型地址的指定嵌套JSON格式
CSV竖线分隔数据转指定JSON格式实现方法
需求说明
- 地址分为Primary(主地址)、Work(工作地址)两类,地址为多值属性,同一人员可拥有2个主地址。
输入CSV格式(分隔符为竖线)
"f_name"|"l_name"|"address_type"|"address_line_1"|"city"|"state"|"postal_code"|"country" Brad|Pitt|Primary|"18 Atherton"|Irvine|CA|"92620-2501"|USA Brad|Pitt|work|"1325 S Grand Ave"|Santa Ana|CA|"92705-4406"|USA
期望输出JSON格式
{ "f_name": "Brad", "l_name": "Pitt", "parsed_address": [ { "address_type": "Primary", "address": [ { "address_line_1": "18 Atherton", "city": "Irvine", "state": "CA", "postal_code": "92620-2501", "country": "USA" } ] }, { "address_type": "work", "address": [ { "address_line_1": "1325 S Grand Ave", "city": "Santa Ana", "state": "CA", "postal_code": "92705-4406", "country": "USA" } ] } ] }
原有尝试代码
df = pd.read_csv("file") g_cols = ['f_name','l_name'] address_field = ['address'] cols = ['address_line_1', 'address_line_2', 'address_line_3', 'city', 'state', 'postal_code', 'country'] for i in g_cols: if i in dict_val.keys(): g_cols[g_cols.index(i)] = dict_val[i] for i in cols: if i in dict_val.keys(): cols[cols.index(i)] = dict_val[i] df2 = df.drop_duplicates().groupby(g_cols)[cols].apply(lambda x: x.to_dict('records')).reset_index( name=address_field).to_dict('record')
调整方案
原有代码的问题是只按姓名维度做了一次分组,没有嵌套按地址类型分组的逻辑,需要调整分组层级:
- 读取CSV时指定竖线分隔符,正确处理引号包裹的字段
- 先按
姓名+地址类型分组,组装每个地址类型对应的地址明细数组 - 再按
姓名分组,把不同类型的地址对象组装为parsed_address数组
完整可运行代码
import pandas as pd import json # 1. 读取CSV,指定分隔符为竖线,自动处理引号 df = pd.read_csv("your_file.csv", sep="|", quoting=1) # quoting=1对应csv.QUOTE_ALL,匹配输入的引号格式 # 地址明细字段列表 address_detail_cols = ['address_line_1', 'address_line_2', 'address_line_3', 'city', 'state', 'postal_code', 'country'] # 第一层分组维度:姓名+地址类型 first_group_cols = ['f_name', 'l_name', 'address_type'] # 第二层分组维度:仅姓名 second_group_cols = ['f_name', 'l_name'] # 如果你有字段映射dict_val,在这里先替换列名,逻辑和你原有代码一致 # dict_val = {"xxx": "yyy"} # 替换为你实际的映射表 # for col in first_group_cols + address_detail_cols: # if col in dict_val: # df.rename(columns={col: dict_val[col]}, inplace=True) # 第一次分组:按姓名+地址类型,生成每个类型对应的地址明细数组 step1 = df.drop_duplicates().groupby(first_group_cols)[address_detail_cols]\ .apply(lambda x: x.to_dict('records'))\ .reset_index(name='address') # 第二次分组:按姓名,把所有地址类型的条目组装为parsed_address数组 result = step1.groupby(second_group_cols)[['address_type', 'address']]\ .apply(lambda x: x.to_dict('records'))\ .reset_index(name='parsed_address')\ .to_dict('records') # 如果需要输出JSON字符串,可直接用json.dumps格式化 json_output = json.dumps(result, indent=2, ensure_ascii=False) print(json_output) # 如果要输出为JSON文件,加上下面的代码 # with open("output.json", "w", encoding="utf-8") as f: # json.dump(result, f, indent=2, ensure_ascii=False)
注:你提供的期望输出中work地址的postal_code存在笔误,代码生成结果会自动匹配CSV中的原始值
92705-4406。
内容的提问来源于stack exchange,提问作者Naveen
相关产品推荐
相关产品推荐

