開發人員#

此部分將重點介紹 pandas 的下游應用程式。

將 pandas DataFrame 物件儲存在 Apache Parquet 格式#

Apache Parquet 格式提供儲存在 Parquet 檔案頁尾的檔案和欄位層級的鍵值資料

5: optional list<KeyValue> key_value_metadata

其中 KeyValue

struct KeyValue {
  1: required string key
  2: optional string value
}

為了能忠實地重建 pandas.DataFrame,我們會在 FileMetaData 中儲存一個 pandas 資料金鑰,其值儲存為

{'index_columns': [<descr0>, <descr1>, ...],
 'column_indexes': [<ci0>, <ci1>, ..., <ciN>],
 'columns': [<c0>, <c1>, ...],
 'pandas_version': $VERSION,
 'creator': {
   'library': $LIBRARY,
   'version': $LIBRARY_VERSION
 }}

'index_columns' 欄位中的「描述符」值 <descr0> 為字串(參照欄位)或具有如下所述值的字典。

<c0>/<ci0> 等是包含每個欄位(包括索引欄位)的資料金鑰的字典。其 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'

  • 其他 Python 物件:'object'

numpy_type 是欄位的實體儲存類型,是儲存資料的底層 NumPy 陣列的 str(dtype) 的結果。因此,對於 datetimetz,這是 datetime64[ns],而對於類別,它可能是任何受支援的整數類別類型。

metadata 欄位為 None,但下列情況除外

  • datetimetz{'timezone': 時區, 'unit': 'ns'},例如 {'timezone', 'America/New_York', 'unit': 'ns'}'unit' 為選用,若省略則假設為奈秒。

  • categorical{'num_categories': K, 'ordered': is_ordered, 'type': $TYPE}

    • 這裡的 'type' 為選用,可以是巢狀的 pandas 類型規格(但非類別型)。

  • unicode{'encoding': 編碼}

    • 編碼為選用,若未指定則為 UTF-8。

  • object{'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'
 }}