如何将嵌套列表格式数据与独立列名列表转换为Pandas DataFrame
嗨,我完全懂你现在的困惑——明明数据和列名都摆在这儿,用Pandas的常规方法却要么格式全乱,要么弹出让人摸不着头脑的报错,那种"list indices must be integers or slices, not str"的提示确实让人头大,我来给你拆解清楚问题,再给你最直接的解决方案。
首先先帮你搞懂那个报错的根源:你大概率尝试过直接写data['fields']这种代码去取数据,但别忘了data本身是一个列表,列表只能用整数索引(比如data[0]取第一个元素),根本不能用字符串'fields'来定位,这就是报错的原因。而你直接用pd.DataFrame(data)或json_normalize(data)的时候,Pandas会把每个字典里的fields当成一个单独的列,不会自动把里面的列表展开成多列,所以才会得到奇怪的单列表格。
接下来给你上最简洁高效的解决方法:
我们只需要先把每个字典里的fields列表单独提取出来,拼成一个新的行数据列表,再传给Pandas DataFrame,同时指定列名就搞定了。具体代码如下:
import pandas as pd # 你的原始数据 data = [ {'fields': ['2024-10-07T21:22:01', 'USER-A', 21, 0, 0, 21]}, {'fields': ['2024-10-07T21:18:28', 'USER-B', 20, 20, 0, 0, 0, 45]} ] cols = ['Created On', 'Created By', 'Transaction Count (ALL)', 'X Pending', 'X Cancelled (X)', 'X Completed (Y)'] # 遍历每个字典,取出fields对应的列表,组装成行数据集合 rows = [item['fields'] for item in data] # 用行数据和列名创建DataFrame df = pd.DataFrame(rows, columns=cols)
运行这段代码后,你就能得到结构完全正确的DataFrame了。针对你提到的"数据元素数和列名数可能不一致"的情况,Pandas会自动在缺失的位置填充NaN,完全不用担心格式混乱。
再给你掰扯下这个方法为什么好使:
- 列表推导式
[item['fields'] for item in data]会挨个遍历data里的每个字典,把每个字典中fields对应的列表单独拎出来,这些列表就是DataFrame的每一行数据。 - 之后用
pd.DataFrame(rows, columns=cols)把这些行数据组装成表格,并用cols作为列名,完美匹配你想要的结构。
如果你之前执着于用json_normalize,其实也能实现,只是多一步展开列的操作,代码如下(本质和上面的方法逻辑一致,只是路径不同):
from pandas import json_normalize # 先把数据扁平化,得到只有fields列的DataFrame df = json_normalize(data) # 把fields列的每个列表展开成单独的列 df = df['fields'].apply(pd.Series) # 给列重命名为指定的列名 df.columns = cols
不过第一种方法更直接高效,我更推荐你用第一种。
最后再给你吃颗定心丸:如果你的真实数据行元素数和列名数是对齐的,那生成的DataFrame会完美对应每一列,不会出现多余的NaN,完全符合你的需求。
备注:内容来源于stack exchange,提问作者Alex F

