2015-10-13 2 views
2

Мне нужно сохранить Pandas DataFrame вместе с некоторыми метаданными в файл в формате JSON. (Формат JSON является обязательным требованием.)Сохранение Pandas DataFrame и метаданных в формат JSON

фона
A) Я могу успешно читать/писать мое довольно большую панду Dataframe из/в формат JSON с использованием DataFrame.to_json() и DataFrame.from_json(). Нет проблем.

B) У меня нет экономии мои метаданные (Dict) в формате JSON проблемы с использованием json.dump()/json.load()


Моя первая попытка
Поскольку Панды не поддерживает метаданные DataFrame непосредственно, моя первая мысль была в

top_level_dict = {} 
top_level_dict['data'] = df.to_dict() 
top_level_dict['metadata'] = {'some':'stuff'} 
json.dump(top_level_dict, fp) 


режимы отказов
C) Я обнаружил, что даже упрощённый случай

df_dict = df.to_dict() 
json.dump(df_dict, fp) 

терпит неудачу с:

TypeError: key (u'US', 112, 5, 80, 'wl') is not a string 

D) Исследуя, я обнаружил, что дополнение также выходит из строя.

df.to_json(fp) 
json.load(fp) 

терпит неудачу с

384    raise ValueError("No JSON object could be decoded") 
ValueError: Expecting : delimiter: line 1 column 17 (char 16) 

Получается, что формат Панды JSON и библиотека JSON в Python не совместимы.

Моя первая мысль гоняться способ модифицировать df.to_dict() выход C, чтобы сделать его доступным для библиотеки JSON в Python, но я продолжаю слышать «Если вы изо всех сил, чтобы сделать что-то в Python, вы вероятно, делает это неправильно ». в моей голове.


Вопрос
Что такое канонический/рекомендуемый метод для добавления метаданных к панде DataFrame и хранению в JSON-формате файл?

Python 2.7.10
Панды 0,17

Edit 1:
Хотя пробуя большой ответ Эвана Райта, я нашел источник моих проблем: панды (по состоянию на 0.17) не любит экономить Мульти -Indexed DataFrames для JSON. Библиотека, которую я создал для сохранения моих (многоиндексированных) DataFrames, спокойно выполняет df.reset_index() перед вызовом DataFrame.to_json(). Мой новый код не был. Так было DataFrame.to_json() отрываясь на MultiIndex.

Занятие: Прочитайте документацию детей, даже если это ваша собственная документация.

Edit 2:

Если вам нужно хранить как DataFrame и метаданные в одного объекта JSON, увидеть мой ответ ниже.

ответ

2

Вы должны иметь возможность просто помещать данные в отдельные строки.

Запись:

f = open('test.json', 'w') 
df.to_json(f) 
print >> f 
json.dump(metadata, f) 

Reading:

f = open('test.json') 
df = pd.read_json(next(f)) 
metdata = json.loads(next(f)) 
+0

Запись в виде двух отдельных строк в файле. Хорошая техника. –

1

На мой вопрос, я ошибочно заявил, что я нуждался в JSON в файле. В этой ситуации ответ Эвана Райт - мое предпочтительное решение.

В моем случае, я действительно должен хранить вывод JSON в виде одного «blob» в базе данных, поэтому мой подход, основанный на использовании словаря, кажется необходимым.

Если вы так же должны хранить данные и метаданные в одном JSON сгустка, следующий код будет работать:

top_level_dict = {} 
top_level_dict['data'] = df.to_dict() 
top_level_dict['metadata'] = {'some':'stuff'} 
with open(FILENAME, 'w') as outfile: 
    json.dump(top_level_dict, outfile) 

Просто убедитесь, что DataFrame однократно индексированные. Если это многоиндексированный, сбросьте индекс (т. Е. df.reset_index()), прежде чем делать это.

Чтение данных обратно в:

with open(FILENAME, 'r') as infile: 
    top_level_dict = json.load(infile) 

df_as_dict = top_level_dict.pop('data', {}) 
df = pandas.DataFrame().as_dict(df_as_dict) 

meta = top_level_dict['metadata'] 

На этом этапе вам необходимо заново создать многоиндексной (если применимо)

Смежные вопросы