Python:含非唯一列的Pandas DataFrame与JSON/字典互转问题
解决DataFrame含非唯一列时与JSON的双向序列化问题
我之前也碰到过DataFrame带重复列名时序列化的坑,分享几个亲测有效的解决方案,覆盖序列化、反序列化和复制粘贴的问题:
1. 先搞定非唯一列的序列化障碍
默认的to_dict()或to_json()会因为字典键必须唯一而报错或丢失数据,核心思路是要么让列名唯一,要么换一种不依赖唯一键的序列化结构:
方法一:给重复列名添加区分后缀
这种方式最直接,先给重复列名加上序号后缀,确保列名唯一后再序列化:
import pandas as pd # 示例DataFrame(含重复列) df = pd.DataFrame([[1, 2], [3, 4]], columns=['col', 'col']) # 给重复列名添加序号后缀 df_unique = df.copy() col_counts = df_unique.columns.value_counts() # 遍历所有重复的列名 for duplicate_col in col_counts[col_counts > 1].index: # 找到该列名出现的所有位置 col_indices = [i for i, c in enumerate(df_unique.columns) if c == duplicate_col] # 逐个添加后缀 for idx in col_indices: df_unique.columns.values[idx] = f"{duplicate_col}_{idx + 1}" # 现在可以正常转为JSON可序列化对象或JSON字符串 serialized_dict = df_unique.to_dict(orient='records') serialized_json = df_unique.to_json(orient='records', indent=2)
方法二:用嵌套结构保留原始列名
如果不想修改列名,可以把每一行的字段转为(列名, 值)的嵌套字典结构,避开唯一键限制:
def df_to_serializable(df): """把DataFrame转为保留原始列名的序列化结构""" return [ [{"column": col, "value": val} for col, val in zip(df.columns, row)] for row in df.itertuples(index=False, name=None) ] # 示例使用 serialized_data = df_to_serializable(df) # 输出结构:[[{'column':'col','value':1}, {'column':'col','value':2}], ...]
2. 实现双向转换(序列化→反序列化)
针对上面两种序列化方法,对应写反序列化函数,还原回原始DataFrame:
对应方法一的反序列化(还原后缀列名)
def dict_to_df(serialized_dict, original_columns): """从带后缀的字典结构还原原始DataFrame""" df_restored = pd.DataFrame(serialized_dict) # 把列名还原为原始重复列名 df_restored.columns = original_columns return df_restored # 用法:后端需把原始列名单独传给前端 original_cols = df.columns.tolist() # 前端返回序列化数据后,还原DataFrame df_restored = dict_to_df(returned_serialized_dict, original_cols)
对应方法二的反序列化(解析嵌套结构)
def serializable_to_df(serialized_data): """从嵌套结构还原原始DataFrame""" rows = [] original_columns = None for row_items in serialized_data: row_values = [] if original_columns is None: # 从第一行提取原始列名 original_columns = [item["column"] for item in row_items] for item in row_items: row_values.append(item["value"]) rows.append(row_values) return pd.DataFrame(rows, columns=original_columns) # 用法 df_restored = serializable_to_df(returned_serialized_data)
3. 解决复制粘贴困难的问题
如果是序列化后的文本太长导致复制出错,可以试试这两个技巧:
- 序列化时用
indent参数格式化输出,让结构更清晰,复制更不易出错:import json # 给JSON字符串加缩进 formatted_json = json.dumps(serialized_dict, indent=2) - 尽量避免手动复制粘贴,后端通过API接口直接传输数据,或者将序列化结果保存为本地JSON文件,通过文件传递比手动复制可靠得多。
内容的提问来源于stack exchange,提问作者Ludo
相关产品推荐
相关产品推荐

