如何将 pandas 列中的 JSON 数据转换为新列

Posted

技术标签:

【中文标题】如何将 pandas 列中的 JSON 数据转换为新列【英文标题】:How to convert JSON data inside a pandas column into new columns 【发布时间】:2018-03-05 14:26:32 【问题描述】:

我有这个简短版本的 ADSB json 数据,并希望将其转换为 dataFrame 列,如 Icao、Alt、Lat、Long、Spd、Cou.....

在 Alperen 告诉我这样做之后

df = pd.read_json('2016-06-20-2359Z.json', lines=True), 

我可以将它加载到 DataFrame 中。但是,df.acList

['Id':10537990,'Rcvr':1,'HasSig':假,... 名称:acList,dtype:对象

如何获取 Icao、Alt、Lat、Long、Spd、Cou 数据?

“src”:1, “饲料”:[ “身份证”:1, "name":"ADSBexchange.com", “极地图”:假 ], “srcFeed”:1, “showSil”:真, “showFlg”:真, “showPic”:真, “flgH”:20, “flgW”:85, “交流清单”:[ “身份证”:11281748, “接收”:1, “哈西格”:假, "Icao":"AC2554", “坏”:假, "注册":"N882AS", "FSeen":"\/日期(1466467166951)\/", “TSecs”:3, “CMsgs”:1, "Alt":0, “Tisb”:假, “TrkH”:假, "类型":"CRJ2", "MDL":"2001 庞巴迪公司 CL-600-2B19", “人”:“庞巴迪”, "CNum":"7503", "Op":"EXPRESSJET AIRLINES INC - 亚特兰大, GA", "OpIcao":"ASQ", "平方":"", “VsiT”:0, “世贸中心”:2, “物种”:1, “引擎”:“2”, “EngType”:3, “EngMount”:1, “米尔”:假, "凑":"美国", “HasPic”:假, “有兴趣”:假, "航班数":0, “接地”:假, "速度类型":0, “CallSus”:假, "TT":"一", "Trt":1, “年份”:“2001” , “身份证”:11402205, “接收”:1, “哈西格”:真, “信号”:110, "Icao":"ADFBDD", “坏”:假, "FSeen":"\/日期(1466391940977)\/", “TSecs”:75229, “CMsgs”:35445, “Alt”:8025, “Galt”:8025, "Alt":0, "呼叫":"TEST1234", “Tisb”:假, “TrkH”:假, "平方":"0262", “帮助”:假, “VsiT”:0, "世贸中心":0, “物种”:0, "EngType":0, "EngMount":0, “米尔”:真, "凑":"美国", “HasPic”:假, “有兴趣”:假, "航班数":0, “接地”:真, "速度类型":0, “CallSus”:假, "TT":"一", “Trt”:1 ], “总Ac”:4231, "lastDv":"636019887431643594", "shtTrlSec":61, “stm”:1466467170029

【问题讨论】:

【参考方案1】:

如果您的数据已经在 pandas DataFrame 的 acList 列中,只需执行以下操作:

import pandas as pd
pd.io.json.json_normalize(df.acList[0])

Alt AltT    Bad CMsgs   CNum    Call    CallSus Cou EngMount    EngType ... Sqk TSecs   TT  Tisb    TrkH    Trt Type    VsiT    WTC Year
0   NaN 0   False   1   7503    NaN False   United States   1   3   ...     3   a   False   False   1   CRJ2    0   2   2001
1   8025.0  0   False   35445   NaN TEST1234    False   United States   0   0   ... 0262    75229   a   False   False   1   NaN 0   0   NaN

从 pandas 1.0 开始,导入应该是:

import pandas as pd
pd.json_normalize(df.acList[0])

【讨论】:

这是在 Python 2.7 上的,对吧?我无法在 Python 3 上执行此操作。请您帮我解决一下吗? @Hamid 这是 Python 3。如果您在将代码发布到 SO 时遇到问题,请使用Pandasjson 或其他任何方式进行标记,我们将尽力为您提供帮助。干杯! 如果一行或多行有None,意味着某些记录没有可用数据怎​​么办? @Regressor 你可以通过将None 替换为 来解决,可以检查my answer【参考方案2】:

@Sergey 的回答为我解决了这个问题,但我遇到了问题,因为我的数据框列中的 json 被保存为字符串而不是对象。我必须添加映射列的附加步骤:

import json
import pandas as pd
pd.io.json.json_normalize(df.acList.apply(json.loads))

【讨论】:

感谢您为我的案例工作,我在第一列中有 JSON 数据,我想将其转置到其他列 这行得通,但是如果除了我想保持原样的其他列(它们是常规列)之外,我还有要转换为多个列的这个列怎么办。我怎样才能做到这一点? 不确定,我真的没有要检查的 pandas env 设置,但也许您可以搜索“flatMap”功能?【参考方案3】:

由于pandas 1.0, json_normalize 在***命名空间中可用。 因此使用:

import pandas as pd
pd.json_normalize(df.acList[0])

【讨论】:

【参考方案4】:

我还不能评论 ThinkBonobo 的回答,但如果列中的 JSON 不完全是字典,您可以继续使用 .apply 直到它出现。所以在我的情况下

import json
import pandas as pd

json_normalize(
    df
    .theColumnWithJson
    .apply(json.loads)
    .apply(lambda x: x[0]) # the inner JSON is list with the dictionary as the only item
)

【讨论】:

有用的贡献。在我的 Panda 0.24.2 数据中,最后一行不是必需的。这可能特定于您的数据。 IE。我的看起来像 'key':value 也许你的看起来像 ['key':value]【参考方案5】:

在我的情况下,我有一些缺失值 (None),然后我创建了一个更具体的代码,该代码在创建新列后也会删除原始列:

for prefix in ['column1', 'column2']:
    df_temp = df[prefix].apply(lambda x:  if pd.isna(x) else x)
    df_temp = pd.io.json.json_normalize(df_temp)
    df_temp = df_temp.add_prefix(prefix + '_')
    df.drop([prefix], axis=1, inplace=True)
    df = pd.concat([df, df_temp], axis = 1, sort=False)

【讨论】:

以上是关于如何将 pandas 列中的 JSON 数据转换为新列的主要内容,如果未能解决你的问题,请参考以下文章

将 pandas 列中的列表转换为字符串

如何将 json 转换为 pandas 数据框?

将pandas列中的列表列表转换为字符串

将 json 转换为 Pandas 数据框

pandas:如何将字典转换为转置数据框? [复制]

无法将 groupby 数据集转换为 pandas 中的 json [重复]