Чтение и запись нескольких словарей в файл csv по вертикали

#python #json #pandas #csv #dictionary

Вопрос:

У меня есть несколько словарей в формате json ‘some.json’, которые выглядят так

 {  "my_dict" : {  'key1': 'value1',   'key2': 'value2',   'key3': 'value3'  },  "my_dict2" : {  'key8': 'value8',   'key9': 'value9',   'key10': 'value10'  } }  

И ключ, и значение являются строками. Я хотел бы экспортировать его в csv вертикальный формат, а затем прочитать его обратно в json файл. Например, когда я добавляю элемент в csv формат my_dict on, он также будет добавлен в json файл.

Требуемая производительность

 my_dict key1,value1 key2,value2 key3,value3 my_dict2 key8,value8 key9,value9 key10,value10  

До сих пор у меня было решение, но проблема в том, что названия словарей не записаны в csv-файле, поэтому их нельзя прочитать обратно в файл json

 import pandas as pd  with open('some.json') as f_input:  df = pd.read_json(f_input)  df = df.bfill(axis='columns') df.iloc[:, 0].to_csv('some.csv', encoding='utf-8', header=False)  

Комментарии:

1. Вы хотите записать два dict в один файл с именем dict в качестве разделителя каждого dict?

2. @Corralien да, именно так! На самом деле это больше, чем 2 дикта, но я могу зациклить его. Проблема в том, чтобы прочитать его обратно и записать на требуемом дикте.

3. Можно ли использовать диктант типа dod = {'my_dict': my_dict, 'my_dict2': my_dict2} диктанта или аналогичную структуру?

4. Обновите свой пост функциональным образцом вашего файла «some.json», пожалуйста.

5. Словари не в «формате json», это не имеет смысла. JSON-это формат сериализации на основе текста

Ответ №1:

Создайте новый файл с file.write именами для дикт:

 import json  with open('some.json') as f:   d = json.load(f)   #sample d = { "my_dict" : { 'key1': 'value1', 'key2': 'value2', 'key3': 'value3'},   "my_dict2" : { 'key8': 'value8', 'key9': 'value9', 'key10': 'value10'}}   with open("some1.csv", 'w') as f:  for k, v in d.items():  f.write(k   'n')  for k1, v1 in v.items():  f.write(f"{k1},{v1}n")  

 my_dict key1,value1 key2,value2 key3,value3 my_dict2 key8,value8 key9,value9 key10,value10  

И для обратного чтения:

 df = pd.read_csv("some1.csv", names=['a','b'])   m = df['b'].isna() df['new'] = df['a'].where(m).ffill() s = df[~m].set_index(['new','a'])['b']  d = {level: s.xs(level).to_dict() for level in s.index.levels[0]} print (d) {'my_dict': {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'},  'my_dict2': {'key8': 'value8', 'key9': 'value9', 'key10': 'value10'}}  

Редактировать:

Если формат должен быть изменен:

 d = { "my_dict" : { 'key1': 'value1', 'key2': 'value2', 'key3': 'value3'},   "my_dict2" : { 'key8': 'value8', 'key9': 'value9', 'key10': 'value10'}}  with open("some1.csv", 'w') as f:  for k, v in d.items():  for k1, v1 in v.items():  f.write(f"{k},{k1},{v1}n")   my_dict,key1,value1 my_dict,key2,value2 my_dict,key3,value3 my_dict2,key8,value8 my_dict2,key9,value9 my_dict2,key10,value10  

 s = pd.read_csv("some1.csv", names=['b'], squeeze=True) print (s) my_dict key1 value1  key2 value2  key3 value3 my_dict2 key8 value8  key9 value9  key10 value10 Name: b, dtype: object   d = {level: s.xs(level).to_dict() for level in s.index.levels[0]} print (d) {'my_dict': {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'},  'my_dict2': {'key8': 'value8', 'key9': 'value9', 'key10': 'value10'}}  

Ответ №2:

Немного банально, но производит именно тот ввод, который вам нужен:

 [f'{col}n{df[col].dropna().to_csv(header=False)}' for col in df.columns)]  

Вы можете либо ''.join(...) и затем записать за один раз, либо добавить mode='a', to_csv , чтобы выходные данные были добавлены непосредственно в какой-либо файл.

Ответ №3:

Я исправил твой some.json файл:

 {  "my_dict": {  "key1": "value1",   "key2": "value2",   "key3": "value3"  },  "my_dict2": {  "key8": "value8",   "key9": "value9",   "key10": "value10"  } }  

Теперь вы можете преобразовать свой файл json в файл csv:

 pd.read_json('some.json', orient='index').stack().to_csv('some.csv', header=False)  

Ваш some.csv файл выглядит так:

 my_dict,key1,value1 my_dict,key2,value2 my_dict,key3,value3 my_dict2,key8,value8 my_dict2,key9,value9 my_dict2,key10,value10  

Примечание: с помощью вышеуказанного формата вы можете легко использовать свой csv-файл в Excel, если вам это нужно.

Операция отката:

 d = pd.read_csv('some.csv', header=None, index_col=0).groupby(0, sort=False)   .apply(lambda x: {k: v for k, v in zip(x[1], x[2])}).to_dict() print(d)  # Output: {'my_dict': {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'},  'my_dict2': {'key8': 'value8', 'key9': 'value9', 'key10': 'value10'}}  

Комментарии:

1. Это работает замечательно, пока я не получил ошибку, когда перечитал ее ValueError: Cannot remove 1 levels from an index with 1 levels: at least one level must be left.

2. это работает, но выходные данные отсортированы в алфавитном порядке. Так, например, my_dict-это zebra, а my_dict2-apple в моем файле json. Результатом будет {'apple':...}, {'zebra':...}

3. Я обновил свой ответ. Если вы хотите сохранить порядок вашего исходного файла json, установите sort=False в качестве параметра groupby else удалить его.