我正在阅读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类型?或我可以做些什么来修改上面的代码来处理这种情况?
答案 0 :(得分:0)
从熊猫文档中:
因为NaN是浮点数,所以一列甚至有一个缺失值的整数都将转换为浮点dtype
从0.24版开始,存在一些扩展的整数类型,它们能够保存缺失值。转换为dtype="Int64"
您可以在下面找到更多信息 https://pandas.pydata.org/pandas-docs/stable/user_guide/integer_na.html
编辑:箭头中建议的解决方法是
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的所有积分