pandas 字符串负宽度填充报 Negative buffer resize
PyArrow字符串列把负width传给填充内核可能报ArrowInvalid。pandas3.1.0已有保护;旧版可按接口约定将负宽度规范为零,保留缺失值和原数据。
PyArrow字符串列执行 s.str.ljust(-5),没有返回原字符串,而是抛出 pyarrow.lib.ArrowInvalid: Negative buffer resize。pandas 3.0.6 配合 PyArrow25.0.1有这条具体路径,pad、center、rjust也受相同的负宽度条件影响。
先核对 width 是否真的为负,以及列是否使用PyArrow字符串存储。相同调用在Python字符串后端正常,不代表值里存在坏字符,也不应先把整列强制转换成普通字符串。
负宽度进入了 Arrow 的缓冲区计算
Python字符串填充的宽度不足时,字符串应保持原样。pandas3.0.6的相关Arrow路径直接把负width传给 utf8_lpad、utf8_rpad或utf8_center,没有先规范为零,底层由此可能计算出非法缓冲区大小。
下面用一列包含中文、空字符串和缺失值的数据说明输入;它是示例,不是性能测试:
import pandas as pd
s = pd.Series(['ab', '中文', '', pd.NA], dtype='string[pyarrow]')
width = -5
result = s.str.pad(width=max(width, 0), side='right', fillchar=' ')
示例假设width已按应用接口确认是整数。把负数限制为零,保留“不足宽度不填充”的含义;仍通过原来的pad调用处理side和fillchar,不能用“负数就直接return”顺便跳过其他非法参数检查。
如果width来自外部配置,业务本身不允许负数,应在输入边界拒绝它并报告配置错误。只有接口约定沿用Python的负宽度语义时,才采用上述规范化方式。
正式3.1.0已加入宽度保护
pandas3.1.0的Arrow字符串实现已在选择填充内核前把负width改为零,正式发行说明也包含这项修正。3.1.0要求Python3.11及以上,升级需一并检查项目支持的Python、PyArrow及pandas兼容范围;不能只在另一个终端安装新包,而让报错任务仍加载旧环境。
暂时保留3.0.6时,可对已确认的输入做上述局部调整,不必全局改变字符串后端。astype(str)可能改变缺失值表示,转换整个DataFrame也会牵连其他列,均不属于这条宽度问题的必要处理。
检查结果时,负宽度和零宽度都应保留原值与缺失位置;正宽度仍按left、right、both的约定补齐。特别核对空字符串、中文、缺失值,以及非法side和fillchar仍按接口报错。这里的宽度是字符串操作的宽度,不是终端里中文字符实际占用的显示列数。


