Pandas 在包含Null的int列上推断架构的拼花地板问题

Pandas 在包含Null的int列上推断架构的拼花地板问题,pandas,amazon-s3,parquet,pyarrow,Pandas,Amazon S3,Parquet,Pyarrow,我正在阅读s3键,并使用熊猫将其转换为拼花地板。在转换成拼花地板之前,我正在对其进行类型转换,以便pyarrow能够正确推断模式 该代码段如下所示: df = pd.read_csv(io.BytesIO(s3.get_object(Bucket=s3_bucket, Key=s3_key)['Body'].read()), sep='\t', error_bad_lines=False, warn_bad_lines=True) df['col_name'] = df['col_name']

我正在阅读s3键,并使用熊猫将其转换为拼花地板。在转换成拼花地板之前,我正在对其进行类型转换,以便pyarrow能够正确推断模式

该代码段如下所示:

df = pd.read_csv(io.BytesIO(s3.get_object(Bucket=s3_bucket, Key=s3_key)['Body'].read()), sep='\t', error_bad_lines=False, warn_bad_lines=True)

df['col_name'] = df['col_name'].astype('int')

table = pa.Table.from_pandas(df)
buf = pa.BufferOutputStream()
pq.write_table(table, buf, compression='snappy')
到目前为止还不错

问题是,当int列有空值时,pandas会将其作为一个对象。有没有办法把它打成int。一种方法是先使用fillna(0)或99999,然后再进行类型转换。它工作了,但随后为Null,0或99999在该列中具有不同的含义


你知道怎么把它输入int吗?或者我可以做些什么来修改上面的代码来处理这种情况?

来自pandas文档:

因为NaN是一个浮点,所以一列整数(甚至缺少一个值)被强制转换为浮点数据类型

自版本0.24以来,有一些扩展整数类型能够保存缺失的值。类型转换为
dtype=“Int64”

你可以在下面找到更多信息

编辑:箭头中建议的解决方法是

import pandas as pd
import pyarrow as pa


def from_pandas(df):
    """Cast Int64 to object before 'serializing'"""
    for col in df:
        if isinstance(df[col].dtype, pd.Int64Dtype):
            df[col] = df[col].astype('object')
    return pa.Table.from_pandas(df)


def to_pandas(tbl):
    """After 'deserializing', recover the correct int type"""
    df = tbl.to_pandas(integer_object_nulls=True)

    for col in df:
        if (pa.types.is_integer(tbl.schema.field_by_name(col).type) and
            pd.api.types.is_object_dtype(df[col].dtype)):
                df[col] = df[col].astype('Int64')

    return df


df = pd.Series([0, 1, None, 2, 822215679726100500], dtype='Int64', name='x').to_frame()
# df = pd.Series([0, 1, 3, 2, 822215679726100500], dtype='Int64', name='x').to_frame()
# df = pd.Series([0, 1, 3, 2, 15], dtype='Int64', name='x').to_frame()
# df = pd.Series([0, 1, 3, 2, 15], dtype='int16', name='x').to_frame()

df2 = to_pandas(from_pandas(df))    
df2.dtypes

所有归功于Thomas Buhrmann

让我试试,因为我不确定pyarrow是否会将其解析为整数或其他内容。我希望它的数据类型与外部表中的数据类型相同。当然可以。您可能会从箭头处得到错误::(