【发布时间】:2023-04-05 01:51:01
【问题描述】:
我有一个 Pandas 数据框,其中一列在每一行中包含一个非嵌套的 json 对象。
js
0 {"k1":"1","k2":"A","k3":"X"}
1 {"k1":"2","k2":"B","k3":"X"}
2 {"k1":"3","k2":"A","k3":"Y"}
3 {"k1":"4","k2":"D","k4":"M"}
这样创建的:
import pandas as pd
L0 = ['{"k1":"1","k2":"A","k3":"X"}',
'{"k1":"2","k2":"B","k3":"X"}',
'{"k1":"3","k2":"A","k3":"Y"}',
'{"k1":"4","k2":"D","k4":"M"}']
df = pd.DataFrame({'js':L0})
我想把 json-objects 变成他们自己的数据框:
k1 k2 k3 k4
0 1 A X NaN
1 2 B X NaN
2 3 A Y NaN
3 4 D NaN M
目前我知道的唯一方法是使用json 模块和df.iterrows():
import json
all_json = []
for _,row in df.iterrows():
all_json.append(json.loads(row["js"]))
df2 = pd.DataFrame.from_dict(all_json)
有没有更好的方法来做到这一点,最好不用迭代?
编辑 1:
感谢您的回答。
我已经在我自己的方法采用158 ms ± 4.01 ms 的真实数据上使用ast.literal_eval 对三种建议的方法进行计时:
df = df.apply(lambda x: ast.literal_eval(x[0]), 1).apply(pd.Series) 接受640 ms ± 7.8 ms
df['js'].apply(ast.literal_eval).apply(pd.Series) 接受636 ms ± 19 ms
pd.DataFrame(df.js.apply(ast.literal_eval).tolist()) 接受180 ms ± 5.11
正如建议的那样,第三种方法是最快的,但遗憾的是它们都比iterrows-方法慢,而我的意图是摆脱iterrows以使其更快。
编辑 2:
pd.DataFrame(df["js"].apply(json.loads).tolist()) 接受25.2 ms ± 512 µs 所以我猜我们有一个赢家。
【问题讨论】:
标签: python json pandas dataframe