You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python2.7中PyArrow转字符串为Binary问题求助(CSV转Parquet)

解决Python2.7下Pandas+PyArrow转Parquet时字符串变Binary的问题

我之前在Python2.7环境里处理CSV转Parquet时也踩过这个一模一样的坑——PyArrow总是把Pandas里的字符串列转成binary类型,导致AWS Glue完全没法正常解析。其实核心问题是Python2的str本质是字节类型,PyArrow默认会把它映射成binary,而不是AWS Glue需要的string(utf8)类型。你之前尝试自定义schema没生效,大概率是因为DataFrame里的列还是Python2的str类型,PyArrow转换时优先用数据的实际类型覆盖了你的schema。

下面是亲测有效的解决步骤:

1. 先把DataFrame的字符串列转为Python2的unicode类型

Python2的unicode是真正的字符串类型,PyArrow会把它正确识别为string(utf8),而不是binary。读取CSV后,遍历所有object类型的列(Pandas里字符串默认存在object列),把它们转成unicode

import pandas as pd
import pyarrow as pa
from io import StringIO

# 读取TSV文件
df = pd.read_csv(StringIO(file), delimiter="\t")

# 转换所有object类型列为unicode,处理空值避免报错
for col in df.select_dtypes(include=['object']).columns:
    df[col] = df[col].apply(lambda x: unicode(x) if pd.notnull(x) else None)

2. 构造正确的自定义Schema并强制使用

现在构造schema时,把字符串列明确指定为pa.string(),然后在转换时强制传入这个schema,确保PyArrow按照我们期望的类型生成Parquet:

# 生成列类型映射:object列用pa.string(),其他列自动匹配numpy类型
dtype_mapping = {}
for col in df.columns:
    if df[col].dtype == object:
        dtype_mapping[col] = pa.string()
    else:
        dtype_mapping[col] = pa.from_numpy_dtype(df[col].dtype)

# 构建PyArrow schema
fields = [pa.field(col_name, col_type) for col_name, col_type in dtype_mapping.items()]
my_schema = pa.schema(fields)

# 转换为PyArrow Table,强制使用自定义schema,忽略Pandas索引
table = pa.Table.from_pandas(
    df,
    schema=my_schema,
    preserve_index=False
)

# 写入Parquet文件
table.write_to_file("output.parquet")

额外注意事项

  • 确保你使用的PyArrow版本是支持Python2.7的较新版本(比如0.15.x到0.17.x,PyArrow从0.18开始不再支持Python2),旧版本的类型映射逻辑可能有bug。
  • 如果你的CSV里有特殊字符,转换unicode时可以指定编码(比如unicode(x, 'utf-8')),避免出现编码错误。

这样处理后,Parquet文件里的字符串列就会是string(utf8)类型,AWS Glue就能正常识别和处理了。

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

火山引擎 最新活动