[英]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.