You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas使用read_parquet读取Parquet文件时保留数据类型?

如何在读取Parquet文件时保留嵌套字典的原始数据类型?

你遇到的问题是因为Parquet是强类型存储格式,当pandas的object列中混合了int和np.nan(属于float类型)时,写入Parquet时会被自动推断为float64类型,导致读取后整数变为浮点数,np.nan变为None。以下是几种可行的解决方案:

方案1:使用Pandas可空整数类型替代原生int和np.nan

将原始数据中的int转换为Pandas的Int64可空整数类型,并用pd.NA替代np.nan,这样写入Parquet时能保留整数类型的缺失值:

import pandas as pd
import numpy as np

# 构造使用可空整数类型的DataFrame
df = pd.DataFrame({
    "a": [
        [{"b": pd.Int64Dtype.type(1)}],
        [{"b": pd.NA}]
    ]
})

# 写入Parquet文件
df.to_parquet("a.parquet", engine="pyarrow")

# 读取文件
df_read = pd.read_parquet("a.parquet")
print(df_read)
# 输出:
#              a
# 0    [{'b': 1}]
# 1  [{'b': <NA>}]

# 验证类型
print(type(df_read.iloc[0, 0][0]['b']))  # <class 'int'>
print(type(df_read.iloc[1, 0][0]['b']))  # <class 'pandas._libs.missing.NAType'>

方案2:写入时指定PyArrow Schema强制类型

通过定义PyArrow的Schema,明确嵌套字段的类型为允许null的整数,强制Parquet存储时使用指定类型:

import pandas as pd
import numpy as np
import pyarrow as pa
import pyarrow.parquet as pq

# 原始DataFrame
df = pd.DataFrame({"a": [[{"b": 1}], [{"b": np.nan}]]})

# 定义Schema:a为列表类型,元素是结构体,b字段为允许null的int64
schema = pa.schema([
    pa.field("a", pa.list_(pa.struct([pa.field("b", pa.int64())])))
])

# 转换为PyArrow Table并指定Schema
table = pa.Table.from_pandas(df, schema=schema)

# 写入Parquet文件
pq.write_table(table, "a.parquet")

# 读取文件
df_read = pd.read_parquet("a.parquet")
print(df_read)
# 输出:
#              a
# 0    [{'b': 1}]
# 1  [{'b': <NA>}]

方案3:读取后手动转换类型(仅适合小数据集)

如果无法修改写入逻辑,可以在读取后遍历数据,将符合整数条件的浮点数转回int,None转回np.nan:

import pandas as pd
import numpy as np

df_read = pd.read_parquet("a.parquet")

def convert_nested_types(lst):
    for d in lst:
        for k, v in d.items():
            if v is not None and isinstance(v, float) and v.is_integer():
                d[k] = int(v)
            elif v is None:
                d[k] = np.nan
    return lst

df_read['a'] = df_read['a'].apply(convert_nested_types)
print(df_read)
# 输出:
#              a
# 0    [{'b': 1}]
# 1  [{'b': nan}]

核心原因说明

Parquet是强类型列式存储格式,PyArrow(Pandas默认的Parquet引擎)在处理object列中的混合类型时,会自动选择能覆盖所有值的最宽泛类型(比如int和np.nan会被推断为float64)。要保留原始类型,必须明确指定支持null的整数类型,避免类型自动提升。

内容的提问来源于stack exchange,提问作者user3595632

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 15:45:28