将不同格式的json转换为csv

时间:2019-10-07 12:40:15

标签: python json pandas csv

我知道这个问题已经被问过很多次了,但是我仍然无法解决我的问题,而且我的编程能力也不是很好,所以基本上我有这么多json文件,但是json的格式非常不同,所以我可以熊猫库没有得到我想要的输出,这是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"
        ]
    }
]

当我使用以下简单代码将其与熊猫一起转换时:

import json
import pandas as pd

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

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

问题是csv文件的输出在一个单元格中给了我所有3个名字,就像['James','Bob','David'],['2000 $','5000 $',' 6000 $'] ... ...但是我只想在该单元格中找到一个名字,而不是全部3个,所以我对这些东西还很陌生。

5 个答案:

答案 0 :(得分:1)

是的,您正在得到答案,因为字典中给定键的每个值都包含一个列表,而不是单个元素。因此,在使用这种json格式时,您应该解决两个问题。

data是一个包含两个字典且每个字典具有相同键的列表。任一词典都包含包含列表的键。因此,我们需要遍历第一个列表(以寻址每个字典),然后遍历第二个列表以获取任何指定键的每个值。输出将是您想要的表。应当注意,此代码将起作用,因为"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)

输出:

     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

答案 1 :(得分:0)

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

输出: '

  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

答案 2 :(得分:0)

问题不在函数中,而是在定义json的方式中。因此,大熊猫的输出与应有的完全一样。

您可以简单地进一步格式化数据框以显示所需的输出,而不必以不同的方式读取它。目前,每一列的每一行都是一个列表,因此您需要取消嵌套:

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'])

借助WeNYoBen

,可以实现自制的嵌套功能

答案 3 :(得分:0)

您的数据输入的结构与所需输出的结构不正确,您需要先对其进行修复:

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$

答案 4 :(得分:0)

我想您希望每一行都有ID,名称和薪水。您可以按照以下步骤实现:

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$

基本上,初始数据框df在列表中具有ID,名称和薪水数据,因此您要做的是制作一个新数据框new_df,然后遍历数据框df并追加new_df的数据框(与df_new具有相同的结构),该数据框在各列下具有正确的行值。

无论行中的列表的ID,名称和薪水相同,只要此列表有多长,它都将起作用。