使用 read_parquet 的 Parquet 文件中带有分类列的 Pandas DataFrame?

dav*_*ugh 6 python-3.x pandas parquet pyarrow

我正在将大型 CSV 文件转换为 Parquet 文件以供进一步分析。我将 CSV 数据读入 Pandas 并按dtypes如下方式指定列

_dtype = {"column_1": "float64",
          "column_2": "category",
          "column_3": "int64",
          "column_4": "int64"}

df = pd.read_csv("data.csv", dtype=_dtype)
Run Code Online (Sandbox Code Playgroud)

然后我做一些更多的数据清理并将数据写入 Parquet 以供下游使用。

_parquet_kwargs = {"engine": "pyarrow",
                   "compression": "snappy",
                   "index": False}

df.to_parquet("data.parquet", **_parquet_kwargs)
Run Code Online (Sandbox Code Playgroud)

但是当我使用 Pandas 将数据读入进行进一步分析时,from_parquet我似乎无法恢复类别 dtypes。下列

df = pd.read_parquet("data.parquet")
Run Code Online (Sandbox Code Playgroud)

结果DataFrameobjectdtypes 代替了所需的category.

以下似乎按预期工作

import pyarrow.parquet as pq

_table = (pq.ParquetFile("data.parquet")
            .read(use_pandas_metadata=True))

df = _table.to_pandas(strings_to_categorical=True)
Run Code Online (Sandbox Code Playgroud)

但是我想知道如何使用pd.read_parquet.

Mar*_*cia 6

这是在 中修复的Arrow 0.15,现在下一个代码将列保留为类别(并且性能明显更快):

import pandas

df = pandas.DataFrame({'foo': list('aabbcc'),
                       'bar': list('xxxyyy')}).astype('category')

df.to_parquet('my_file.parquet')
df = pandas.read_parquet('my_file.parquet')
df.dtypes
Run Code Online (Sandbox Code Playgroud)

  • @Topde 当然,切换到镶木地板不仅可以提高速度,还可以保留列的类型和数据的结构。Parquet 文件可以存储多索引、列类型(尤其是分类和日期时间),这对于数据的正确性(以及速度)来说使用 parquet 而不是 CSV 是有意义的。 (3认同)
  • >“保留列的类型”。不幸的是,对于 Pandas,它不保留类型,如这个问题和其他一些问题所示。读取数据帧。尝试`pandas.DataFrame({'foo': [1, 2, 3, 3, 1]}).astype("category")`。`df.dtypes` 显示 `categorical`,但从 parquet 重新加载后,它又回到 int64。使用 pyarrow==9.0.0 进行测试。 (2认同)