Разработчик#
Этот раздел будет посвящен прикладным применениям pandas.
Хранение объектов pandas DataFrame в формате Apache Parquet#
The Apache Parquet формат предоставляет метаданные в виде ключ-значение на уровне файла и столбца, хранящиеся в нижнем колонтитуле файла Parquet:
5: optional list key_value_metadata
где KeyValue является
struct KeyValue {
1: required string key
2: optional string value
}
Так что pandas.DataFrame может быть точно восстановлен, мы сохраняем
pandas ключ метаданных в FileMetaData со значением, хранящимся как:
{'index_columns': [, , ...],
'column_indexes': [, , ..., ],
'columns': [, , ...],
'pandas_version': $VERSION,
'creator': {
'library': $LIBRARY,
'version': $LIBRARY_VERSION
}}
Значения "дескриптора" в 'index_columns' поле являются
строками (ссылающимися на столбец) или словарями со значениями, как описано ниже.
The / и так далее являются словарями, содержащими метаданные
для каждого столбца, включая столбцы индекса. Это имеет JSON-форму:
{'name': column_name,
'field_name': parquet_column_name,
'pandas_type': pandas_type,
'numpy_type': numpy_type,
'metadata': metadata}
См. ниже подробную спецификацию для них.
Дескрипторы метаданных индекса#
RangeIndex может храниться только как метаданные, не требуя сериализации.
Формат дескриптора для них следующий:
index = pd.RangeIndex(0, 10, 2)
{
"kind": "range",
"name": index.name,
"start": index.start,
"stop": index.stop,
"step": index.step,
}
Другие типы индексов должны быть сериализованы как столбцы данных вместе с другими
столбцами DataFrame. Метаданные для них — это строка, указывающая имя
поля в столбцах данных, например '__index_level_0__'.
Если индекс имеет не-None name атрибут, и нет другого столбца с именем, соответствующим этому значению, тогда index.name значение может использоваться как дескриптор. В противном случае (для безымянных индексов и тех, чьи имена совпадают с именами других столбцов) используется устраняющее неоднозначность имя с сопоставлением шаблонов
__index_level_\d+__ должен использоваться. В случаях именованных индексов как столбцов данных, name атрибут всегда хранится в дескрипторах столбцов, как указано выше.
Метаданные столбца#
pandas_type является логическим типом столбца и одним из:
Логический:
'bool'Целые числа:
'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64'Числа с плавающей точкой:
'float16', 'float32', 'float64'Типы даты и времени:
'datetime', 'datetimetz','timedelta'Строка:
'unicode', 'bytes'Categorical:
'categorical'Другие объекты Python:
'object'
The numpy_type является физическим типом хранения столбца, который является результатом str(dtype) для базового массива NumPy, который хранит данные. Так что для datetimetz это datetime64[ns] а для категориального это может быть
любой из поддерживаемых целочисленных категориальных типов.
The metadata поле есть None за исключением:
datetimetz:{'timezone': zone, 'unit': 'ns'}, например,{'timezone', 'America/New_York', 'unit': 'ns'}.'unit'является необязательным, и если опущен, предполагается, что это наносекунды.categorical:{'num_categories': K, 'ordered': is_ordered, 'type': $TYPE}Здесь
'type'является необязательным и может быть вложенной спецификацией типа pandas здесь (но не категориальной)
unicode:{'encoding': encoding}Кодировка необязательна, и если она отсутствует, используется UTF-8
object:{'encoding': encoding}. Объекты могут быть сериализованы и сохранены вBYTE_ARRAYСтолбцы Parquet. Кодировка может быть одной из:'pickle''bson''json'
timedelta:{'unit': 'ns'}.'unit'является необязательным, и если опущено, предполагается, что это наносекунды. Эти метаданные в целом необязательны
Для типов, отличных от этих, 'metadata' ключ может быть
опущен. Реализации могут предполагать None если ключ отсутствует.
В качестве примера полностью сформированных метаданных:
{'index_columns': ['__index_level_0__'],
'column_indexes': [
{'name': None,
'field_name': 'None',
'pandas_type': 'unicode',
'numpy_type': 'object',
'metadata': {'encoding': 'UTF-8'}}
],
'columns': [
{'name': 'c0',
'field_name': 'c0',
'pandas_type': 'int8',
'numpy_type': 'int8',
'metadata': None},
{'name': 'c1',
'field_name': 'c1',
'pandas_type': 'bytes',
'numpy_type': 'object',
'metadata': None},
{'name': 'c2',
'field_name': 'c2',
'pandas_type': 'categorical',
'numpy_type': 'int16',
'metadata': {'num_categories': 1000, 'ordered': False}},
{'name': 'c3',
'field_name': 'c3',
'pandas_type': 'datetimetz',
'numpy_type': 'datetime64[ns]',
'metadata': {'timezone': 'America/Los_Angeles'}},
{'name': 'c4',
'field_name': 'c4',
'pandas_type': 'object',
'numpy_type': 'object',
'metadata': {'encoding': 'pickle'}},
{'name': None,
'field_name': '__index_level_0__',
'pandas_type': 'int64',
'numpy_type': 'int64',
'metadata': None}
],
'pandas_version': '1.4.0',
'creator': {
'library': 'pyarrow',
'version': '0.13.0'
}}