#python #json #pandas #numpy
#python #json #pandas #numpy
Вопрос:
Объекты не могут быть сериализованы в json, поэтому их необходимо преобразовать или проанализировать с помощью пользовательского класса JSONEncoder.
фрейм данных pandas имеет ряд методов, таких from_records
как чтение данных json. Однако, когда вы считываете эти данные json обратно, они возвращаются как int64 вместо метки времени.
Существует много способов скинуть кошку в pandas. Каков наилучший способ сохранить структуры данных при чтении и записи json?
Комментарии:
1. Pandas не является универсальным декодером json. Он может (корректно) обрабатывать только файлы json определенного формата и, как известно, плохо справляется с обработкой глубоко вложенных файлов json. ИМХО, ваш текущий вопрос неясен .
2. @SergeBallesta вопрос в том, что pandas по какой-то причине проделал хакерскую работу по преобразованию данных в json и из него. попробуйте записать из pandas df в json что-нибудь, что содержит pd. Отметьте объект Timestamp, а затем прочитайте его обратно в df. у вас будет два разных объекта
Ответ №1:
Как бы то ни было, я сохраняю фреймы данных pandas в базе данных Postgres, и я хочу сохранить индекс с временным интервалом. Я использую следующий код:
class db_JsonEncodedDataFrameWithTimezone(db.TypeDecorator):
"""Enables JSON storage by encoding and decoding on the fly."""
impl = db.Text
def process_bind_param(self, value, dialect):
if value is not None and isinstance(value, pd.DataFrame):
timezone = value.index.tz.zone
df_json = value.to_json(orient="index")
data = {'timezone': timezone, 'df': df_json, 'index_name': value.index.name}
value = json.dumps(data)
return value
def process_result_value(self, value, dialect):
if value is not None:
data = json.loads(value)
df = pd.read_json(data['df'], orient="index")
df.index = df.index.tz_localize('UTC')
df.index = df.index.tz_convert(data['timezone'])
df.index.name = data['index_name']
value = df
return value
def compare_values(self, x, y):
from pandas.util.testing import assert_frame_equal
try:
assert_frame_equal(x, y, check_names=True, check_like=True)
return True
except (AssertionError, ValueError, TypeError):
return False
Комментарии:
1. похоже, что json не подходит для сериализации временных меток или других объектов. спасибо за альтернативу!
Ответ №2:
Если я правильно понял вашу проблему, вы ищете способ сериализации, сохраняющий типы данных фрейма данных.
Проблема в том, что форматы обмена внутри используют несколько типов: только строки для csv, строки и числа для json. Конечно, есть способы давать подсказки по форматированию во время чтения (формат даты для столбцов даты в csv), и, как правило, легко преобразовать обратно в правильный тип после извлечения, я думаю, что вы надеетесь более естественным способом. Как было предложено Attack68, вы могли бы использовать базу данных, но, например, база данных SQLite была бы отключена, поскольку у нее нет внутреннего типа даты.
ИМХО, простым способом было бы положиться на старый добрый pickle
модуль. В конце концов, фрейм данных — это объект Python, который содержит другие объекты Python, поэтому pickle хорош в сериализации этого. Единственное, что следует помнить, это то, что во время десериализации pandas должны быть импортированы перед вызовом pickle.load
.
Но я только что протестировал с (крошечным) фреймом данных, содержащим различные типы данных, и pickle был великолепен, поскольку правильно сохранял и восстанавливал их.