【问题标题】:Json to excel using python使用 python 实现 Json 的 Excel
【发布时间】:2021-11-29 01:41:12
【问题描述】:

Json 代码:下面是我使用 API 从站点提取的 json 数据格式

response={
      "result": [
        {
          "id": "1000",
          "title": "Fishing Team View",
          "sharedWithOrganization": True,
          "ownerId": "324425",
          "sharedWithUsers": ["1223","w2qee3"],
          "filters": [
            {
              "field": "tag5",
              "comparator": "==",
              "value": "fishing"
            }
          ]
        },
        {
          "id": "2000",
          "title": "Farming Team View",
          "sharedWithOrganization": False,
          "ownerId": "00000",
          "sharedWithUsers": [
            "00000",
            "11111"
          ],
          "filters": [
            {
              "field": "tag5",
              "comparator": "!@",
              "value": "farming"
            }
          ]
        }
      ]
    }

Python 代码:我正在使用下面的代码来解析 json 数据,但我无法过滤到不同的列,特别是过滤部分到单独的列中,比如内部过滤器我想制作字段,比较器单独的列

    records=[]
    for data in response['result']:
        id = data['id']
        title = data['title']
        sharedWithOrganization = data['sharedWithOrganization']
        ownerId = data['ownerId'] 
        sharedWithUsers = '|'.join(data['sharedWithUsers'])
        filters = data['filters']
        print(filters)
        records.append([id,title,sharedWithOrganization,ownerId,sharedWithUsers])
        
        #print(records)
    
        
        
    ExcelApp = win32.Dispatch('Excel.Application')
    ExcelApp.Visible= True
    
    #creating excel and renaming sheet
    
    wb = ExcelApp.Workbooks.Add()
    ws= wb.Worksheets(1)
    ws.Name="Get_Views"
        
        
        
    #assigning header value
    header_labels=('Id','Title','SharedWithOrganization','OwnerId','sharedWithUsers')
    for index,val in enumerate(header_labels):
        ws.Cells(1, index+1).Value=val
        
        
        
    row_tracker = 2
    column_size = len(header_labels)
    
    for row in records:
        ws.Range(ws.cells(row_tracker,1),ws.cells(row_tracker,column_size)).value = row
        row_tracker +=1

我正在做 API pull 我得到这种格式,我将 .json 格式传递给 python 以实现数据到 excel 但我无法将列表数据过滤到单独的列中,你能帮我吗

【问题讨论】:

    标签: python python-3.x excel pandas dataframe


    【解决方案1】:

    使用DictWriter,您可以将所需的列写入.csv 文件,您可以在Excel 中打开该文件。

    代码:

    from csv import DictWriter
    
    response = { ... }
    with open("result.csv", "w", newline="") as f:
        writer = DictWriter(
            f,
            ("id", "title", "sharedWithOrganization", "ownerId", "sharedWithUsers"),
            extrasaction="ignore"
        )
        writer.writeheader()
        for obj in response["result"]:
            writer.writerow({**obj, "sharedWithUsers": "|".join(obj["sharedWithUsers"])})
    

    或者你可以使用csv.writer (会消耗更少的内存,因为不会复制所有字段)

    import csv
    from operator import itemgetter
    
    response = { ... }
    
    keys = "id", "title", "sharedWithOrganization", "ownerId", "sharedWithUsers"
    getter = itemgetter(*keys)
    with open("result.csv", "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(keys)
        for obj in response["result"]:
            row = getter(obj)
            writer.writerow(row[:-1] + ("|".join(row[-1]),))
    

    【讨论】:

      【解决方案2】:

      下面的代码生成out.csv,可以用Excel打开。
      请注意,代码不需要任何外部库。

      import csv
      
      response={
            "result": [
              {
                "id": "1000",
                "title": "Fishing Team View",
                "sharedWithOrganization": True,
                "ownerId": "324425",
                "sharedWithUsers": ["1223","w2qee3"],
                "filters": [
                  {
                    "field": "tag5",
                    "comparator": "==",
                    "value": "fishing"
                  }
                ]
              },
              {
                "id": "2000",
                "title": "Farming Team View",
                "sharedWithOrganization": False,
                "ownerId": "00000",
                "sharedWithUsers": [
                  "00000",
                  "11111"
                ],
                "filters": [
                  {
                    "field": "tag5",
                    "comparator": "!@",
                    "value": "farming"
                  }
                ]
              }
            ]
          }
      fields = ['id','title','sharedWithOrganization','ownerId','sharedWithUsers']
      data = []
      for entry in response['result']:
        data.append(['|'.join(entry[f]) if isinstance(entry[f],list) else entry[f] for f in fields])
      with open('out.csv','w') as f:
        writer = csv.writer(f)
        writer.writerow(fields)
        for line in data:
          writer.writerow(line)
      

      out.csv

      id,title,sharedWithOrganization,ownerId,sharedWithUsers
      1000,Fishing Team View,True,324425,1223|w2qee3
      2000,Farming Team View,False,00000,00000|11111
      

      【讨论】:

        【解决方案3】:

        您可以在下面看到我是如何做到的,因为它返回一个列表,您可以使用 [0] 选择列表的第一项,例如 datafield["filters"][0]["field"],您也可以创建一个 csv 文件并将其导入到 excel 中。

        import json
        import csv
        
        rows = []
        headers = ["Id", "Title", "SharedWithOrganization", "OwnerId","SharedWithUsers","field", "comparator", "value"]
        
        for datafield in response["result"] :
            susers = ""
            for u in datafield["sharedWithUsers"] :
                susers = susers + u + "|"
            susers = susers[:-1]
            if datafield["sharedWithOrganization"] :
                boolval = "TRUE"
            else :
                boolval = "FALSE"
            rows.append([datafield["id"], datafield["title"], boolval,     datafield["ownerId"], susers, datafield["filters"][0]["field"], datafield["filters"][0]["comparator"], datafield["filters"][0]["value"]])
        
        
        with open('responseOutput.csv', 'w', encoding='UTF8', newline='') as f:
            writer = csv.writer(f)
        
            # write the header
            writer.writerow(headers)
        
            # write multiple rows
            writer.writerows(rows)
        

        【讨论】:

        • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
        【解决方案4】:

        您可以使用pd.json_normalize 对Json 进行规范化:指定不同的参数record_path= 以分别读取标签result 和标签filters 下的字段的不同深度。

        然后,将 2 个生成的数据帧连接在一起,如下所示:

        # read fields under tag `result`
        df_result = pd.json_normalize(response, record_path=['result'])
        
        # read fields under tag `filters` within `result`
        df_filters = pd.json_normalize(response, record_path=['result', 'filters'])
        
        # Join 2 resultant dataframes together
        df = df_result.join(df_filters).drop('filters', axis=1)
        
        # Join fields in `sharedWithUsers`
        df['sharedWithUsers'] = df['sharedWithUsers'].str.join('|')
        

        结果:

        print(df)
        
             id              title  sharedWithOrganization ownerId sharedWithUsers field comparator    value
        0  1000  Fishing Team View                    True  324425     1223|w2qee3  tag5         ==  fishing
        1  2000  Farming Team View                   False   00000     00000|11111  tag5         !@  farming
        

        【讨论】:

          【解决方案5】:

          试试:

          df = pd.Series(response).explode().apply(pd.Series).reset_index(drop=True)
          df = df.join(df['filters'].explode().apply(pd.Series)).drop(columns=['filters'])
          df['sharedWithUsers'] = df['sharedWithUsers'].str.join('|')
          

          输出:

               id              title  sharedWithOrganization ownerId sharedWithUsers field comparator    value
          0  1000  Fishing Team View                    True  324425     1223|w2qee3  tag5         ==  fishing
          1  2000  Farming Team View                   False   00000     00000|11111  tag5         !@  farming
          

          【讨论】:

            猜你喜欢
            • 2021-02-24
            • 2018-09-26
            • 2022-12-30
            • 2021-03-25
            • 1970-01-01
            • 2016-10-10
            • 2021-09-28
            • 2020-01-09
            • 2017-11-29
            相关资源
            最近更新 更多