【问题标题】:Pandas data structure help - dealing with nested JSONPandas 数据结构帮助——处理嵌套的 JSON
【发布时间】:2022-07-13 01:15:34
【问题描述】:

我正在尝试规范化从我的数据库中提取的数据。在这些数据中有一个名为ExtraData 的列,它以嵌套的json 表示。我的ExtraData JSON 可能是这些情况之一:

{"Data":{"Parties":[{"ID":"JackyID","Role":12}],"NbIDs":1}} #One party identified
{"Data":{"Parties":[{"ID":"JackyID","Role":12},{"ID":"SamNumber","Role":10}],"NbIDs":2}} #Two Parties identified
{"Data":{"Parties":[],"NbIDs":0}} #No parties identified
{"Data": None} #No data

当要提取 ID(当事方的 ID - String 数据类型)和 Role(Int 数据类型 - 当 Role=12 时指买家,当 Role=10 时指卖家)的值时,当什么都不存在时写“”,我'正在使用以下方法:

def parse_extra_data(data_str):
    response = {'Buyer': '', 'Seller': ''}
    try:
        data_json = json.loads(data_str)
    except:
        return response
    for party in data_json['Data']['Parties']:
        if party['Role'] == 12:
            response['Buyer'] = party['ID']
        elif party['PartyRole'] == 122:
            response['Seller'] = party['ID']        
    return response

现在,当我想将此方法应用于我的代码时:

import json
import pandas.io.json as pd_json

query="SELECT OrderID, ExtraData from tbl_data;"
test_data= crsr.execute(query)
columns_test = [column[0] for column in crsr.description]
rows = [list(x) for x in test_data]
df = pd.DataFrame(rows, columns=columns_test)
for i,row in df.iterrows():
    test = json.dumps(row['Data'])
    data = pd_json.loads(test)
    data_json = json.loads(data)
    df['Buyer'] = df.apply(lambda row: parse_extra_data(data_json['Data'])['Buyer'], axis=1)
    df['Seller'] = df.apply(lambda row: parse_extra_data(data_json['Data'])['Seller'], axis=1)
df.rename(columns={
    'OrderID' :'ID of the order'
 }, inplace = True) 
df = df[['ID of the order','Buyer', 'Seller']]

执行这段代码时,df如下:

>>print(df)
ID of the order   |Buyer     | Seller
--------------------------------------
321               |          |              
456               |          |    
789               |          |    
987               |          |            

print(data_json) 仅显示来自ExtraData 的第一个 JSON。

我做错了什么?以及如何解决?如果我们把上面的场景作为数据库输入,df 应该是这样的:

>>print(df)
ID of the order   |Buyer  | Seller
---------------------------------------
321               |JackyID|              #Transaction 1 we have info about the buyer
456               |JackyID| SamNumber    #Transaction 2 we have infos about the buyer and the seller
789               |       |              #Transaction 3 we don't have any infos about the parties
987               |       |              #Transaction 4 we don't have any infos about the parties

【问题讨论】:

    标签: python json pandas


    【解决方案1】:

    好吧,尽管我认为错误在df.apply 行中(看看how to use it),但没有数据库中的数据作为示例来尝试复制错误,因为您使用的是@ 987654323@ 以行为参数的函数,但它从未在 lambda 定义中调用,这意味着任何列都不会受到 parse_extra_data 函数的影响。

    apply的使用示例:

    df.apply(lambda x: func(x['col1'],x['col2']),axis=1)
    

    【讨论】:

      【解决方案2】:

      给定:

      data = [{'Data': {'Parties': [{'ID': 'JackyID', 'Role': 12}], 'NbIDs': 1}}, {'Data': {'Parties': [{'ID': 'JackyID', 'Role': 12}, {'ID': 'SamNumber', 'Role': 10}], 'NbIDs': 2}}, {'Data': {'Parties': [], 'NbIDs': 0}}, {'Data': None}]
      

      在做:

      df = pd.json_normalize([x['Data'] for x in data if x['Data']], 'Parties', 'NbIDs')
      df.Role.replace({12:'Buyer', 10:'Seller'}, inplace=True)
      df = df.pivot(columns='Role', index='NbIDs', values='ID')
      print(df)
      

      输出:

      Role     Buyer     Seller
      NbIDs
      1      JackyID        NaN
      2      JackyID  SamNumber
      

      【讨论】:

      • 运行时我有TypeError: string indices must be integersdf = pd.json_normalize([x['Data'] for x in data if x['Data']], 'Parties', 'NbIDs')
      猜你喜欢
      • 2013-11-23
      • 2014-04-15
      • 1970-01-01
      • 2021-10-06
      • 2021-08-26
      • 1970-01-01
      • 2021-01-02
      • 2022-11-12
      • 1970-01-01
      相关资源
      最近更新 更多