如何将CSV日志中每组3条JSON记录合并为单条DataFrame记录?
如何将CSV中每3行JSON记录合并为一条结构化DataFrame
问题背景
我有一个.csv日志文件,每个客户端对应3条JSON格式的记录,示例如下:
{"name":"John","phone":"08847","politic":"on","ville":"LA","isTest":"false","source":"t3_1"} {"data":{"name":"John","phone":"+8847","city":"LA","source":"t3_1","cameF":"a1"},"token":"bd67a","isTest":false} {"data":{"responseId":"R_2hs","city":"LA","cameF":"cpl_agency2","source":"t3_1"},"success":true,"ts":1721394844,"message":null}
目前用pandas.read_csv读取后,DataFrame把每行JSON拆成了多列,示例结构如下:
| t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | t9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | "name":"John" | "phone":"08847" | "politic":"on" | "ville":"LA" | "isTest":"false" | "source":"t3_1" | NaN | NaN | NaN |
| 1 | {"data":{"name":"John" | phone:"+08847" | city:"LA" | source:"t3_1" | cameF:"a1"} | token:"bd67a" | isTest:false} | NaN | NaN |
| 2 | {"data":{"responseId":"R_2hs" | city:"LA" | cameF:"a1" | source:"t3_1"} | success:true | ts:1721394844 | message:null | NaN | NaN |
我需要将每3行合并为一条记录,最终得到包含所有字段的结构化DataFrame,示例如下:
| name | phone | politic | ville | isTest | source | name | phone | city | source | cameF | token | rId | city | cameF | source | success | ts | message |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| John | 08847 | on | LA | false | t3_1 | John | +08847 | LA | t3_1 | a1 | bd67a | R_2hs | LA | a1 | t3_1 | true | 1721394844 | null |
解决方案
步骤1:正确读取原始日志行
不要用read_csv直接拆分列,先按行读取整个文件并跳过前42行测试数据:
import pandas as pd import json # 按行读取文件,跳过前42行测试数据 with open('/content/drive/MyDrive/Colab Notebooks/in/post.csv', 'r') as f: lines = [line.strip() for line in f.readlines()[42:]]
步骤2:每3行分组并解析JSON
将读取到的行按每3个元素分组,分别解析每组内的3条JSON,再合并所有字段:
# 将列表按每3行分为一组 groups = [lines[i:i+3] for i in range(0, len(lines), 3)] processed_data = [] for group in groups: # 解析第一条JSON(基础用户信息) first_entry = json.loads(group[0]) # 解析第二条JSON(带token的详细信息) second_entry = json.loads(group[1]) # 解析第三条JSON(响应结果信息) third_entry = json.loads(group[2]) # 合并所有字段,给重名字段加前缀避免覆盖 merged_record = { # 第一条记录的字段 'name_base': first_entry['name'], 'phone_base': first_entry['phone'], 'politic': first_entry['politic'], 'ville': first_entry['ville'], 'isTest_base': first_entry['isTest'], 'source_base': first_entry['source'], # 第二条记录的字段 'name_detail': second_entry['data']['name'], 'phone_detail': second_entry['data']['phone'], 'city_detail': second_entry['data']['city'], 'source_detail': second_entry['data']['source'], 'cameF_detail': second_entry['data']['cameF'], 'token': second_entry['token'], 'isTest_detail': second_entry['isTest'], # 第三条记录的字段 'rId': third_entry['data']['responseId'], 'city_response': third_entry['data']['city'], 'cameF_response': third_entry['data']['cameF'], 'source_response': third_entry['data']['source'], 'success': third_entry['success'], 'ts': third_entry['ts'], 'message': third_entry['message'] } processed_data.append(merged_record) # 转换为结构化DataFrame final_df = pd.DataFrame(processed_data)
步骤3:调整列名(可选)
如果需要和目标结构的重复列名保持一致,可修改merged_record中的键名,但注意pandas会自动给重复列名添加后缀(如name.1),建议保留前缀避免混淆。
验证结果
运行display(final_df)即可得到合并后的结构化记录。
内容的提问来源于stack exchange,提问作者mikhailtugushev
相关产品推荐
相关产品推荐

