简体中文 繁體中文 English Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français Japanese

站内搜索

搜索

活动公告

通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,将及时处理!
10-23 09:31

使用pandas库高效输出JSON格式数据的技巧与方法从基础操作到高级应用解决数据转换中的常见问题

SunJu_FaceMall

3万

主题

238

科技点

3万

积分

大区版主

碾压王

积分
32126

立华奏

发表于 2025-10-3 01:30:25 | 显示全部楼层 |阅读模式 [标记阅至此楼]

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

在数据分析和处理领域,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易于阅读和编写、易于机器解析和生成的特点,被广泛应用于Web应用程序和API中。Python的pandas库作为数据分析的强大工具,提供了丰富的功能来处理JSON数据。本文将深入探讨如何使用pandas高效地输出JSON格式数据,从基础操作到高级应用,并解决数据转换过程中可能遇到的常见问题。

1. pandas与JSON基础

1.1 pandas库简介

pandas是Python中一个强大的数据分析库,提供了快速、灵活和富有表现力的数据结构,旨在使数据清洗和分析工作变得更加简单。它主要提供了两种数据结构:Series(一维数组)和DataFrame(二维表格型数据结构)。

1.2 JSON数据格式简介

JSON是一种轻量级的数据交换格式,基于JavaScript的一个子集。它采用完全独立于编程语言的文本格式,但也使用了类似于C语言家族的习惯。JSON数据可以表示为:

• 对象(无序的键/值对集合)
• 数组(有序的值列表)
• 值(字符串、数字、布尔值、null、对象或数组)

1.3 pandas与JSON的结合

pandas提供了read_json()和to_json()两个核心函数,分别用于读取和输出JSON数据。这两个函数提供了丰富的参数选项,可以满足不同场景下的JSON数据处理需求。

2. 基础操作:读取与输出JSON数据

2.1 使用pandas读取JSON数据

pandas的read_json()函数可以将JSON数据转换为DataFrame。以下是基本用法:
  1. import pandas as pd
  2. # 从JSON字符串读取
  3. json_string = '{"name": "John", "age": 30, "city": "New York"}'
  4. df = pd.read_json(json_string, orient='index')
  5. print(df)
  6. # 从JSON文件读取
  7. df = pd.read_json('data.json')
  8. print(df)
复制代码

orient参数是read_json()函数中非常重要的参数,它指定了JSON字符串的预期格式:

• ‘split’:字典包含索引、列和数据
• ‘records’:列表形式的记录,如[{column -> value}, … , {column -> value}]
• ‘index’:字典形式的索引,如{index -> {column -> value}}
• ‘columns’:字典形式的列,如{column -> {index -> value}}
• ‘values’:仅值数组

2.2 使用pandas输出JSON数据

pandas的to_json()方法可以将DataFrame转换为JSON格式。以下是基本用法:
  1. import pandas as pd
  2. # 创建一个DataFrame
  3. data = {'name': ['John', 'Anna', 'Peter'],
  4.         'age': [30, 25, 40],
  5.         'city': ['New York', 'London', 'Paris']}
  6. df = pd.DataFrame(data)
  7. # 将DataFrame转换为JSON字符串
  8. json_string = df.to_json()
  9. print(json_string)
  10. # 将DataFrame保存为JSON文件
  11. df.to_json('output.json')
复制代码

与read_json()类似,to_json()方法也提供了orient参数,用于指定输出的JSON格式:
  1. # 不同的orient参数示例
  2. print("orient='records':")
  3. print(df.to_json(orient='records'))
  4. print("\norient='index':")
  5. print(df.to_json(orient='index'))
  6. print("\norient='columns':")
  7. print(df.to_json(orient='columns'))
  8. print("\norient='split':")
  9. print(df.to_json(orient='split'))
复制代码

2.3 处理嵌套JSON数据

在实际应用中,我们经常遇到嵌套的JSON数据。pandas可以通过json_normalize()函数处理这种情况:
  1. import pandas as pd
  2. from pandas import json_normalize
  3. # 嵌套JSON数据
  4. nested_json = [
  5.     {
  6.         "name": "John",
  7.         "age": 30,
  8.         "contact": {
  9.             "email": "john@example.com",
  10.             "phone": "123-456-7890"
  11.         },
  12.         "hobbies": ["reading", "swimming"]
  13.     },
  14.     {
  15.         "name": "Anna",
  16.         "age": 25,
  17.         "contact": {
  18.             "email": "anna@example.com",
  19.             "phone": "098-765-4321"
  20.         },
  21.         "hobbies": ["painting", "traveling"]
  22.     }
  23. ]
  24. # 使用json_normalize处理嵌套JSON
  25. df = json_normalize(nested_json)
  26. print(df)
  27. # 如果需要进一步处理嵌套的列表或字典
  28. df_hobbies = json_normalize(nested_json, 'hobbies', ['name', 'age'])
  29. print("\nHobbies DataFrame:")
  30. print(df_hobbies)
复制代码

3. 高级应用:复杂JSON数据处理

3.1 自定义JSON输出格式

有时,我们需要按照特定的格式输出JSON数据,这可以通过自定义函数和to_json()的参数组合来实现:
  1. import pandas as pd
  2. import json
  3. # 创建DataFrame
  4. data = {'name': ['John', 'Anna', 'Peter'],
  5.         'age': [30, 25, 40],
  6.         'city': ['New York', 'London', 'Paris']}
  7. df = pd.DataFrame(data)
  8. # 自定义JSON输出格式
  9. def custom_json_format(df):
  10.     # 将DataFrame转换为字典列表
  11.     records = df.to_dict(orient='records')
  12.    
  13.     # 添加自定义结构
  14.     custom_output = {
  15.         "metadata": {
  16.             "count": len(df),
  17.             "columns": list(df.columns)
  18.         },
  19.         "data": records
  20.     }
  21.    
  22.     return json.dumps(custom_output, indent=4)
  23. # 使用自定义函数
  24. custom_json = custom_json_format(df)
  25. print(custom_json)
复制代码

3.2 处理大型JSON数据

处理大型JSON文件时,内存可能会成为问题。以下是几种处理大型JSON数据的方法:
  1. import pandas as pd
  2. import json
  3. # 假设我们有一个大型JSON文件,包含多个记录
  4. # 我们可以逐行读取并处理
  5. def process_large_json(file_path, chunk_size=1000):
  6.     chunks = []
  7.     with open(file_path, 'r') as file:
  8.         # 假设每行是一个JSON对象
  9.         chunk = []
  10.         for line in file:
  11.             try:
  12.                 record = json.loads(line.strip())
  13.                 chunk.append(record)
  14.                 if len(chunk) >= chunk_size:
  15.                     df_chunk = pd.DataFrame(chunk)
  16.                     chunks.append(df_chunk)
  17.                     chunk = []
  18.             except json.JSONDecodeError:
  19.                 continue
  20.         
  21.         # 处理最后一个可能不满chunk_size的块
  22.         if chunk:
  23.             df_chunk = pd.DataFrame(chunk)
  24.             chunks.append(df_chunk)
  25.    
  26.     # 合并所有块
  27.     if chunks:
  28.         return pd.concat(chunks, ignore_index=True)
  29.     else:
  30.         return pd.DataFrame()
  31. # 使用示例
  32. # large_df = process_large_json('large_data.json')
复制代码
  1. import ijson
  2. import pandas as pd
  3. def stream_json_to_dataframe(file_path, path_to_items):
  4.     """
  5.     使用ijson流式处理大型JSON文件
  6.    
  7.     参数:
  8.         file_path: JSON文件路径
  9.         path_to_items: 指向JSON中项目列表的路径,例如'item'或'users.item'
  10.    
  11.     返回:
  12.         DataFrame
  13.     """
  14.     items = []
  15.     with open(file_path, 'rb') as file:
  16.         for item in ijson.items(file, path_to_items):
  17.             items.append(item)
  18.             # 可以在这里添加条件,只收集部分数据
  19.             # 或者每N个项目创建一个DataFrame并处理
  20.    
  21.     return pd.DataFrame(items)
  22. # 使用示例
  23. # df = stream_json_to_dataframe('large_data.json', 'users.item')
复制代码

3.3 复杂JSON结构的转换

有时我们需要处理更复杂的JSON结构,如包含嵌套对象和数组的JSON。以下是一些处理方法:
  1. import pandas as pd
  2. import json
  3. from pandas import json_normalize
  4. # 复杂的JSON结构
  5. complex_json = {
  6.     "school": "ABC High School",
  7.     "students": [
  8.         {
  9.             "id": 1,
  10.             "name": "John",
  11.             "grades": {
  12.                 "math": 90,
  13.                 "science": 85,
  14.                 "history": 78
  15.             },
  16.             "contacts": [
  17.                 {"type": "email", "value": "john@example.com"},
  18.                 {"type": "phone", "value": "123-456-7890"}
  19.             ]
  20.         },
  21.         {
  22.             "id": 2,
  23.             "name": "Anna",
  24.             "grades": {
  25.                 "math": 95,
  26.                 "science": 92,
  27.                 "history": 88
  28.             },
  29.             "contacts": [
  30.                 {"type": "email", "value": "anna@example.com"},
  31.                 {"type": "phone", "value": "098-765-4321"}
  32.             ]
  33.         }
  34.     ]
  35. }
  36. # 将复杂的JSON转换为DataFrame
  37. def process_complex_json(json_data):
  38.     # 首先提取学生基本信息
  39.     students_df = json_normalize(json_data['students'])
  40.    
  41.     # 提取成绩信息
  42.     grades_df = json_normalize(
  43.         json_data['students'],
  44.         'grades',
  45.         ['id', 'name']
  46.     )
  47.    
  48.     # 提取联系信息
  49.     contacts_df = json_normalize(
  50.         json_data['students'],
  51.         'contacts',
  52.         ['id', 'name']
  53.     )
  54.    
  55.     return {
  56.         'students': students_df,
  57.         'grades': grades_df,
  58.         'contacts': contacts_df
  59.     }
  60. # 处理复杂JSON
  61. result = process_complex_json(complex_json)
  62. print("Students DataFrame:")
  63. print(result['students'])
  64. print("\nGrades DataFrame:")
  65. print(result['grades'])
  66. print("\nContacts DataFrame:")
  67. print(result['contacts'])
复制代码

3.4 使用pandas和自定义编码器处理特殊数据类型

当DataFrame包含特殊数据类型(如datetime、period等)时,直接转换为JSON可能会导致问题。以下是处理方法:
  1. import pandas as pd
  2. import json
  3. from datetime import datetime
  4. # 创建包含特殊数据类型的DataFrame
  5. data = {
  6.     'name': ['John', 'Anna', 'Peter'],
  7.     'join_date': [datetime(2020, 1, 1), datetime(2020, 2, 15), datetime(2019, 11, 30)],
  8.     'last_active': [pd.Timestamp('2021-01-10'), pd.Timestamp('2021-02-20'), pd.Timestamp('2021-01-05')],
  9.     'salary': [50000.50, 60000.75, 75000.25]
  10. }
  11. df = pd.DataFrame(data)
  12. # 自定义JSON编码器
  13. class PandasJSONEncoder(json.JSONEncoder):
  14.     def default(self, obj):
  15.         if hasattr(obj, 'to_json'):
  16.             return obj.to_json()
  17.         elif hasattr(obj, 'isoformat'):
  18.             return obj.isoformat()
  19.         elif isinstance(obj, (pd.Timestamp, pd.Period)):
  20.             return str(obj)
  21.         return super().default(obj)
  22. # 使用自定义编码器
  23. json_str = json.dumps(df.to_dict(orient='records'), cls=PandasJSONEncoder, indent=2)
  24. print(json_str)
  25. # 或者使用pandas的to_json方法并处理日期
  26. df['join_date'] = df['join_date'].dt.strftime('%Y-%m-%d')
  27. df['last_active'] = df['last_active'].dt.strftime('%Y-%m-%d')
  28. json_str = df.to_json(orient='records', date_format='iso')
  29. print("\nUsing pandas to_json with date formatting:")
  30. print(json_str)
复制代码

4. 常见问题及解决方案

4.1 处理JSON中的日期和时间

问题:JSON不直接支持日期和时间格式,导致在转换过程中可能丢失日期信息或格式不正确。

解决方案:
  1. import pandas as pd
  2. import json
  3. from datetime import datetime
  4. # 创建包含日期的DataFrame
  5. df = pd.DataFrame({
  6.     'date': pd.date_range('2020-01-01', periods=3),
  7.     'value': [10, 20, 30]
  8. })
  9. # 方法1:在转换为JSON前将日期格式化为字符串
  10. df['date_str'] = df['date'].dt.strftime('%Y-%m-%d')
  11. json_str = df[['date_str', 'value']].to_json(orient='records')
  12. print("Method 1 - Pre-format dates:")
  13. print(json_str)
  14. # 方法2:使用自定义编码器
  15. class DateTimeEncoder(json.JSONEncoder):
  16.     def default(self, obj):
  17.         if isinstance(obj, (datetime, pd.Timestamp)):
  18.             return obj.isoformat()
  19.         return super().default(obj)
  20. # 转换为字典列表,然后使用自定义编码器
  21. records = df.to_dict(orient='records')
  22. json_str = json.dumps(records, cls=DateTimeEncoder, indent=2)
  23. print("\nMethod 2 - Custom encoder:")
  24. print(json_str)
  25. # 方法3:使用pandas的to_json方法并指定日期格式
  26. json_str = df.to_json(orient='records', date_format='iso')
  27. print("\nMethod 3 - pandas to_json with date_format='iso':")
  28. print(json_str)
复制代码

4.2 处理非ASCII字符

问题:JSON数据中包含非ASCII字符时,可能会出现编码问题。

解决方案:
  1. import pandas as pd
  2. # 创建包含非ASCII字符的DataFrame
  3. df = pd.DataFrame({
  4.     'name': ['张三', '李四', '王五'],
  5.     'city': ['北京', '上海', '广州'],
  6.     'description': ['喜欢运动', '热爱音乐', '爱好阅读']
  7. })
  8. # 方法1:指定ensure_ascii=False
  9. json_str = df.to_json(orient='records', force_ascii=False)
  10. print("Method 1 - force_ascii=False:")
  11. print(json_str)
  12. # 方法2:在保存到文件时指定编码
  13. df.to_json('non_ascii.json', orient='records', force_ascii=False)
  14. # 读取非ASCII JSON文件
  15. df_read = pd.read_json('non_ascii.json', orient='records', encoding='utf-8')
  16. print("\nRead back from file:")
  17. print(df_read)
复制代码

4.3 处理NaN和null值

问题:pandas中的NaN值在转换为JSON时可能需要特殊处理。

解决方案:
  1. import pandas as pd
  2. import numpy as np
  3. import json
  4. # 创建包含NaN值的DataFrame
  5. df = pd.DataFrame({
  6.     'id': [1, 2, 3, 4],
  7.     'name': ['John', 'Anna', 'Peter', None],
  8.     'score': [85, np.nan, 92, 78],
  9.     'active': [True, False, None, True]
  10. })
  11. # 方法1:使用to_json的默认行为(NaN转为null)
  12. json_str = df.to_json(orient='records')
  13. print("Method 1 - Default behavior (NaN becomes null):")
  14. print(json_str)
  15. # 方法2:在转换前填充NaN值
  16. df_filled = df.fillna({
  17.     'name': 'Unknown',
  18.     'score': 0,
  19.     'active': False
  20. })
  21. json_str = df_filled.to_json(orient='records')
  22. print("\nMethod 2 - Fill NaN values before conversion:")
  23. print(json_str)
  24. # 方法3:使用自定义处理函数
  25. def custom_nan_handler(obj):
  26.     if isinstance(obj, float) and np.isnan(obj):
  27.         return None  # 或者返回其他自定义值
  28.     return obj
  29. records = df.to_dict(orient='records')
  30. json_str = json.dumps(records, default=custom_nan_handler)
  31. print("\nMethod 3 - Custom NaN handler:")
  32. print(json_str)
复制代码

4.4 处理大型DataFrame的内存问题

问题:当处理大型DataFrame时,直接转换为JSON可能会导致内存不足。

解决方案:
  1. import pandas as pd
  2. import json
  3. # 创建一个大型DataFrame(示例中使用小型DataFrame,但原理相同)
  4. df = pd.DataFrame({
  5.     'id': range(100000),
  6.     'value': [i**2 for i in range(100000)]
  7. })
  8. # 方法1:分块处理并写入文件
  9. def dataframe_to_json_chunks(df, file_path, chunk_size=10000):
  10.     with open(file_path, 'w') as f:
  11.         f.write('[\n')  # 开始JSON数组
  12.         
  13.         for i, chunk in enumerate(np.array_split(df, len(df) // chunk_size + 1)):
  14.             if i > 0:
  15.                 f.write(',\n')  # 在块之间添加逗号
  16.             
  17.             chunk_str = chunk.to_json(orient='records')
  18.             # 去除开头的'['和结尾的']',因为我们已经在文件中写了它们
  19.             chunk_str = chunk_str[1:-1]
  20.             f.write(chunk_str)
  21.         
  22.         f.write('\n]')  # 结束JSON数组
  23. # 使用分块方法
  24. # dataframe_to_json_chunks(df, 'large_output.json')
  25. # 方法2:逐行处理
  26. def dataframe_to_json_lines(df, file_path):
  27.     with open(file_path, 'w') as f:
  28.         for record in df.to_dict(orient='records'):
  29.             f.write(json.dumps(record) + '\n')
  30. # 使用逐行方法
  31. # dataframe_to_json_lines(df, 'large_output.jsonl')
  32. # 方法3:使用生成器减少内存使用
  33. def generate_json_records(df):
  34.     for record in df.to_dict(orient='records'):
  35.         yield json.dumps(record)
  36. # 使用生成器
  37. # with open('large_output.jsonl', 'w') as f:
  38. #     for json_record in generate_json_records(df):
  39. #         f.write(json_record + '\n')
复制代码

4.5 处理复杂的嵌套结构

问题:当JSON包含复杂的嵌套结构时,直接转换为DataFrame可能会丢失信息或结构混乱。

解决方案:
  1. import pandas as pd
  2. from pandas import json_normalize
  3. import json
  4. # 复杂的嵌套JSON
  5. complex_nested_json = {
  6.     "company": "Tech Corp",
  7.     "departments": [
  8.         {
  9.             "name": "Engineering",
  10.             "employees": [
  11.                 {
  12.                     "id": 1,
  13.                     "name": "John",
  14.                     "skills": ["Python", "Java", "SQL"],
  15.                     "projects": [
  16.                         {"name": "Project A", "role": "Lead"},
  17.                         {"name": "Project B", "role": "Developer"}
  18.                     ]
  19.                 },
  20.                 {
  21.                     "id": 2,
  22.                     "name": "Anna",
  23.                     "skills": ["JavaScript", "React", "Node.js"],
  24.                     "projects": [
  25.                         {"name": "Project C", "role": "Developer"},
  26.                         {"name": "Project D", "role": "Consultant"}
  27.                     ]
  28.                 }
  29.             ]
  30.         },
  31.         {
  32.             "name": "Marketing",
  33.             "employees": [
  34.                 {
  35.                     "id": 3,
  36.                     "name": "Peter",
  37.                     "skills": ["SEO", "Content", "Analytics"],
  38.                     "projects": [
  39.                         {"name": "Campaign X", "role": "Manager"},
  40.                         {"name": "Campaign Y", "role": "Analyst"}
  41.                     ]
  42.                 }
  43.             ]
  44.         }
  45.     ]
  46. }
  47. # 方法1:使用json_normalize处理多层嵌套
  48. def process_complex_nested(json_data):
  49.     # 首先提取部门信息
  50.     departments = []
  51.     for dept in json_data['departments']:
  52.         dept_info = {
  53.             'department_name': dept['name'],
  54.             'company': json_data['company']
  55.         }
  56.         departments.append(dept_info)
  57.    
  58.     dept_df = pd.DataFrame(departments)
  59.    
  60.     # 提取员工信息
  61.     employees = []
  62.     for dept in json_data['departments']:
  63.         for emp in dept['employees']:
  64.             emp_info = {
  65.                 'id': emp['id'],
  66.                 'name': emp['name'],
  67.                 'department': dept['name'],
  68.                 'company': json_data['company'],
  69.                 'skills': emp['skills']
  70.             }
  71.             employees.append(emp_info)
  72.    
  73.     emp_df = pd.DataFrame(employees)
  74.    
  75.     # 提取项目信息
  76.     projects = []
  77.     for dept in json_data['departments']:
  78.         for emp in dept['employees']:
  79.             for proj in emp['projects']:
  80.                 proj_info = {
  81.                     'project_name': proj['name'],
  82.                     'role': proj['role'],
  83.                     'employee_id': emp['id'],
  84.                     'employee_name': emp['name'],
  85.                     'department': dept['name'],
  86.                     'company': json_data['company']
  87.                 }
  88.                 projects.append(proj_info)
  89.    
  90.     proj_df = pd.DataFrame(projects)
  91.    
  92.     return {
  93.         'departments': dept_df,
  94.         'employees': emp_df,
  95.         'projects': proj_df
  96.     }
  97. # 处理复杂嵌套JSON
  98. result = process_complex_nested(complex_nested_json)
  99. print("Departments DataFrame:")
  100. print(result['departments'])
  101. print("\nEmployees DataFrame:")
  102. print(result['employees'])
  103. print("\nProjects DataFrame:")
  104. print(result['projects'])
  105. # 方法2:递归处理嵌套结构
  106. def flatten_json(data, parent_key='', sep='_'):
  107.     items = {}
  108.     for k, v in data.items():
  109.         new_key = f"{parent_key}{sep}{k}" if parent_key else k
  110.         if isinstance(v, dict):
  111.             items.update(flatten_json(v, new_key, sep=sep))
  112.         elif isinstance(v, list):
  113.             for i, item in enumerate(v):
  114.                 if isinstance(item, dict):
  115.                     items.update(flatten_json(item, f"{new_key}{sep}{i}", sep=sep))
  116.                 else:
  117.                     items[f"{new_key}{sep}{i}"] = item
  118.         else:
  119.             items[new_key] = v
  120.     return items
  121. # 使用递归扁平化
  122. flattened = flatten_json(complex_nested_json)
  123. flat_df = pd.DataFrame([flattened])
  124. print("\nFlattened DataFrame:")
  125. print(flat_df)
复制代码

5. 最佳实践和性能优化

5.1 选择合适的orient参数

选择正确的orient参数可以显著提高JSON处理的效率和可读性:
  1. import pandas as pd
  2. import time
  3. # 创建一个中等大小的DataFrame
  4. df = pd.DataFrame({
  5.     'id': range(10000),
  6.     'name': [f'Name_{i}' for i in range(10000)],
  7.     'value': [i**2 for i in range(10000)]
  8. })
  9. # 测试不同orient参数的性能
  10. orients = ['split', 'records', 'index', 'columns', 'values']
  11. results = {}
  12. for orient in orients:
  13.     start_time = time.time()
  14.     json_str = df.to_json(orient=orient)
  15.     end_time = time.time()
  16.     results[orient] = {
  17.         'time': end_time - start_time,
  18.         'size': len(json_str)
  19.     }
  20. # 打印结果
  21. print("Performance comparison of different orient parameters:")
  22. for orient, metrics in results.items():
  23.     print(f"{orient}: Time = {metrics['time']:.4f}s, Size = {metrics['size']} bytes")
复制代码

5.2 使用压缩技术减少JSON文件大小

对于大型JSON文件,使用压缩可以显著减少存储空间:
  1. import pandas as pd
  2. import gzip
  3. import json
  4. # 创建一个大型DataFrame
  5. df = pd.DataFrame({
  6.     'id': range(100000),
  7.     'name': [f'Name_{i}' for i in range(100000)],
  8.     'value': [i**2 for i in range(100000)]
  9. })
  10. # 方法1:使用gzip压缩
  11. def save_compressed_json(df, file_path):
  12.     json_str = df.to_json(orient='records')
  13.     with gzip.open(file_path, 'wt', encoding='utf-8') as f:
  14.         f.write(json_str)
  15. # 保存压缩的JSON文件
  16. # save_compressed_json(df, 'large_data.json.gz')
  17. # 读取压缩的JSON文件
  18. def read_compressed_json(file_path):
  19.     with gzip.open(file_path, 'rt', encoding='utf-8') as f:
  20.         json_str = f.read()
  21.     return pd.read_json(json_str, orient='records')
  22. # 读取压缩的JSON文件
  23. # df_read = read_compressed_json('large_data.json.gz')
  24. # 方法2:使用pandas的内置压缩支持
  25. df.to_json('large_data.json.gz', orient='records', compression='gzip')
  26. df_read = pd.read_json('large_data.json.gz', orient='records', compression='gzip')
复制代码

5.3 使用多进程处理大型JSON数据

对于非常大的JSON数据集,可以使用多进程来加速处理:
  1. import pandas as pd
  2. import json
  3. from multiprocessing import Pool, cpu_count
  4. import numpy as np
  5. # 创建一个非常大的DataFrame
  6. large_df = pd.DataFrame({
  7.     'id': range(1000000),
  8.     'name': [f'Name_{i}' for i in range(1000000)],
  9.     'value': [i**2 for i in range(1000000)]
  10. })
  11. # 定义处理函数
  12. def process_chunk(chunk):
  13.     # 这里可以添加任何需要的数据处理逻辑
  14.     # 示例中我们只是将每个值乘以2
  15.     chunk['value'] = chunk['value'] * 2
  16.     return chunk.to_json(orient='records')
  17. # 使用多进程处理
  18. def parallel_json_processing(df, num_processes=None):
  19.     if num_processes is None:
  20.         num_processes = cpu_count()
  21.    
  22.     # 将DataFrame分成多个块
  23.     chunks = np.array_split(df, num_processes)
  24.    
  25.     # 创建进程池
  26.     with Pool(num_processes) as pool:
  27.         results = pool.map(process_chunk, chunks)
  28.    
  29.     # 合并结果
  30.     combined_json = '[' + ','.join(results) + ']'
  31.     return combined_json
  32. # 使用多进程处理
  33. # json_result = parallel_json_processing(large_df)
  34. # df_processed = pd.read_json(json_result)
复制代码

5.4 使用类型优化减少JSON大小

通过优化数据类型,可以减少生成的JSON文件大小:
  1. import pandas as pd
  2. import numpy as np
  3. # 创建一个DataFrame,使用默认数据类型
  4. df_default = pd.DataFrame({
  5.     'id': range(10000),
  6.     'name': [f'Name_{i}' for i in range(10000)],
  7.     'value': [i**2 for i in range(10000)],
  8.     'active': [True if i % 2 == 0 else False for i in range(10000)]
  9. })
  10. # 创建一个DataFrame,使用优化的数据类型
  11. df_optimized = pd.DataFrame({
  12.     'id': range(10000),
  13.     'name': [f'Name_{i}' for i in range(10000)],
  14.     'value': [i**2 for i in range(10000)],
  15.     'active': [True if i % 2 == 0 else False for i in range(10000)]
  16. })
  17. # 优化数据类型
  18. df_optimized['id'] = pd.to_numeric(df_optimized['id'], downcast='unsigned')
  19. df_optimized['value'] = pd.to_numeric(df_optimized['value'], downcast='integer')
  20. df_optimized['active'] = df_optimized['active'].astype('boolean')
  21. # 比较JSON输出大小
  22. json_default = df_default.to_json(orient='records')
  23. json_optimized = df_optimized.to_json(orient='records')
  24. print(f"Default DataFrame JSON size: {len(json_default)} bytes")
  25. print(f"Optimized DataFrame JSON size: {len(json_optimized)} bytes")
  26. print(f"Size reduction: {((len(json_default) - len(json_optimized)) / len(json_default)) * 100:.2f}%")
复制代码

5.5 使用高效的JSON库

除了标准的json库,还可以使用更高效的JSON处理库:
  1. import pandas as pd
  2. import json
  3. import ujson  # 需要安装: pip install ujson
  4. import orjson  # 需要安装: pip install orjson
  5. # 创建一个DataFrame
  6. df = pd.DataFrame({
  7.     'id': range(10000),
  8.     'name': [f'Name_{i}' for i in range(10000)],
  9.     'value': [i**2 for i in range(10000)]
  10. })
  11. # 转换为字典列表
  12. records = df.to_dict(orient='records')
  13. # 使用标准json库
  14. import time
  15. start_time = time.time()
  16. json_str = json.dumps(records)
  17. std_time = time.time() - start_time
  18. std_size = len(json_str)
  19. # 使用ujson
  20. start_time = time.time()
  21. ujson_str = ujson.dumps(records)
  22. ujson_time = time.time() - start_time
  23. ujson_size = len(ujson_str)
  24. # 使用orjson
  25. start_time = time.time()
  26. orjson_bytes = orjson.dumps(records)
  27. orjson_time = time.time() - start_time
  28. orjson_size = len(orjson_bytes)
  29. # 比较结果
  30. print(f"Standard json: Time = {std_time:.4f}s, Size = {std_size} bytes")
  31. print(f"ujson: Time = {ujson_time:.4f}s, Size = {ujson_size} bytes")
  32. print(f"orjson: Time = {orjson_time:.4f}s, Size = {orjson_size} bytes")
复制代码

6. 结论

本文详细介绍了使用pandas库高效输出JSON格式数据的技巧与方法,从基础操作到高级应用,并解决了数据转换中的常见问题。我们学习了如何:

1. 使用pandas的read_json()和to_json()函数进行基本的JSON数据读取和输出
2. 处理嵌套JSON数据,包括使用json_normalize()函数
3. 实现自定义JSON输出格式,满足特定需求
4. 处理大型JSON数据,包括分块处理和流式处理
5. 解决常见问题,如日期时间处理、非ASCII字符、NaN值处理等
6. 优化性能,包括选择合适的orient参数、使用压缩技术、多进程处理等

通过掌握这些技巧和方法,您可以更高效地使用pandas处理JSON数据,无论是在数据分析、Web开发还是API集成等场景中。随着数据量的不断增长和数据处理需求的日益复杂,这些技能将变得越来越重要。

希望本文能帮助您更好地理解和使用pandas处理JSON数据,提高数据处理的效率和质量。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

联系我们|小黑屋|TG频道|RSS |网站地图

Powered by Pixtech

© 2025-2026 Pixtech Team.

>