簡體   English   中英

將不同格式的 json 轉換為 csv

[英]converting json with different format to csv

我知道這已經被問過很多次了,但我仍然沒有解決我的問題,而且我不擅長編程,所以基本上我有這么多 json 文件,但 json 的格式非常不同,所以我無法得到我想要的 output 與 pandas 庫,這是 json 文件的示例。

[
    {
        "Names": [
            "James",
            "Bob",
            "David"
        ],
        "Salary": [
            "2000$",
            "5000$",
            "6000$"
        ],
        "Id": [
            "1",
            "2",
            "3"
        ]
    },
    {
        "Names": [
            "John",
            "Charles",
            "Harry"
        ],
        "Salary": [
            "1000$",
            "2000$",
            "3000$"
        ],
        "Id": [
            "4",
            "5",
            "6"
        ]
    }
]

當我使用以下簡單代碼將其轉換為 pandas 時:

import json
import pandas as pd

df=pd.read_json("test.json")
df.to_csv("results.csv")

https://i.imgur.com/0RMLb89.png

問題是 csv 文件的 output 給我一個單元格中的所有 3 個名稱,就像 ['James', 'Bob', 'David'], ['2000$', '5000$', '6000$' ]...但我只想要一個名字

是的,您得到了這個答案,因為字典中給定鍵的每個值都包含一個列表而不是單個元素。 因此,在使用這種 json 格式時,您應該解決兩個級別。

data是一個列表,其中包含兩個具有相同鍵的字典。 任一字典都包含包含列表的鍵。 因此,我們需要遍歷第一個列表(以尋址每個字典),然后遍歷第二個列表以尋址任何指定鍵的每個值。 output 將成為您想要的表格。 應該注意的是,此代碼將起作用,因為"Names"的列表值的長度與"Salary""Id"相同。

import pandas as pd 
import numpy as np
data = [
    {
        "Names": ["James","Bob","David"],
        "Salary": ["2000$","5000$","6000$"],
        "Id": ["1","2","3"]},
    {
        "Names": ["John","Charles","Harry"],
        "Salary": ["1000$","2000$","3000$"],
        "Id": ["4","5","6"]}
]
to_df = {'Names':[],'Salary':[],'Id':[]}
for i in range(len(data)):
    for j in range(len(data[i]['Id'])):
        to_df['Names'].append(data[i]['Names'][j])
        to_df['Salary'].append(data[i]['Salary'][j])
        to_df['Id'].append(data[i]['Id'][j])
df = pd.DataFrame(to_df)
print(df)

Output:

     Names Salary Id
0    James  2000$  1
1      Bob  5000$  2
2    David  6000$  3
3     John  1000$  4
4  Charles  2000$  5
5    Harry  3000$  6
a = [
    {
        "Names": [
            "James",
            "Bob",
            "David"
        ],
        "Salary": [
            "2000$",
            "5000$",
            "6000$"
        ],
        "Id": [
            "1",
            "2",
            "3"
        ]
    },
    {
        "Names": [
            "John",
            "Charles",
            "Harry"
        ],
        "Salary": [
            "1000$",
            "2000$",
            "3000$"
        ],
        "Id": [
            "4",
            "5",
            "6"
        ]
    }
]

我認為這可能會解決您的問題:

col_names = [k for k,v in a[0].items()]
frames = [pd.io.json.json_normalize(a, str(col)) for col in col_names]
final_df = pd.concat(frames, axis = 1)
final_df.columns = col_names

Output:'

  Id Salary    Names
0  1  2000$    James
1  2  5000$      Bob
2  3  6000$    David
3  4  1000$     John
4  5  2000$  Charles
5  6  3000$    Harry

問題不在 function 中,而是在 json 的定義方式上。 因此,pandas output 正是它應該的樣子。

而不是以不同的方式閱讀它,您可以簡單地格式化您的 dataframe 進一步顯示您想要的 output。 目前每一列的每一行都是一個列表,所以你需要取消嵌套:

import json
import pandas as pd
import numpy as np

df=pd.read_json('data.json')

def unnesting(df, explode):
    idx = df.index.repeat(df[explode[0]].str.len())
    df1 = pd.concat([
        pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
    df1.index = idx

    return df1.join(df.drop(explode, 1), how='left')

unnesting(df,['Names','Salary','Id'])

自制解套 function 感謝WeNYoBen

對於您想要的 output,您的數據輸入結構不正確,您需要先修復該問題:

import json

with open('test.json', 'r') as file:
    data = json.load(file.read())

# flatten the data to {'Name': [...], 'Salary': [...], ...}
d = {}
for elem in data:
    for k, v in elem.items():
        d.setdefault(k, []).extend(v)

df = pd.DataFrame(d).reindex(columns=['Id', 'Names', 'Salary'])

結果:

  Id    Names Salary
0  1    James  2000$
1  2      Bob  5000$
2  3    David  6000$
3  4     John  1000$
4  5  Charles  2000$
5  6    Harry  3000$

我想你希望每一行都有id、name和salary。 您可以按如下方式實現:

import pandas as pd

df=pd.read_json("test.json")

new_df = pd.DataFrame(columns=['id', 'name', 'salary'])
for _, row in df.iterrows():
    new_df = new_df.append(pd.DataFrame(
        {'id': row.Id, 'name': row.Names, 'salary': row.Salary}))

new_df.to_csv("results.csv")

得到結果results.csv

,id,name,salary
0,1,James,2000$
1,2,Bob,5000$
2,3,David,6000$
0,4,John,1000$
1,5,Charles,2000$
2,6,Harry,3000$

Basically the initial dataframe df has the id, names and salary data in lists, so what you do is to make a new dataframe new_df , then loop over dataframe df and append to new_df the dataframe (with same structure as df_new ) that has the values每列下正確的行數。

無論行中的列表有多長,只要 Id、Names 和 Salary 相同,這將起作用...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM