rpy2 R转pandas data.frame时NA值异常 求自定义转换器代码
rpy2 R data.frame转pandas DataFrame类型异常修复方案
问题现象
使用rpy2内置的pandas转换规则时,会出现两类不符合预期的转换结果:
- 整型列的R
NA被错误转换为32位整型最小值-2147483648 - R布尔向量被错误转换为整数0/1,丢失布尔类型属性
- 浮点型
NA转NaN、字符串NA转None的默认转换行为符合预期
复现代码及默认输出如下:
import rpy2.robjects as ro from rpy2.robjects.conversion import localconverter from rpy2.robjects import pandas2ri ro.r( """ f <- function() { return(data.frame(int = c(4L, NA), float = c(1.2, NA), chr = c("A", NA), bool = c(TRUE, FALSE))) } """ ) r_f = ro.globalenv["f"] res = r_f() with localconverter(ro.default_converter + pandas2ri.converter): pd_from_r_df = ro.conversion.rpy2py(res) print(pd_from_r_df)
默认错误输出:
int float chr bool 1 4 1.2 A 1 2 -2147483648 NaN None 0
可直接复用的自定义转换器代码
import rpy2.robjects as ro import pandas as pd import numpy as np from rpy2.robjects.conversion import localconverter, Converter from rpy2.robjects import pandas2ri, IntVector, BoolVector # 基于原有pandas转换器构建修正版转换器 fixed_pandas_converter = Converter("fixed_pandas_conv", template=pandas2ri.converter) @fixed_pandas_converter.rpy2py.register(IntVector) def _convert_r_int(obj): # 识别R整型向量中的NA值,转换为pandas可空Int64类型 arr = np.array(obj, dtype=object) arr[np.array(obj.ro_is_na())] = pd.NA return pd.array(arr, dtype=pd.Int64Dtype()) @fixed_pandas_converter.rpy2py.register(BoolVector) def _convert_r_bool(obj): # 保留布尔类型,将R布尔NA转换为pd.NA arr = np.array(obj, dtype=object) arr[np.array(obj.ro_is_na())] = pd.NA return pd.array(arr, dtype=pd.BooleanDtype()) # 组装最终可用的转换器 my_converter = ro.default_converter + fixed_pandas_converter
使用方法
将原有代码中localconverter传入的转换器替换为上面定义的my_converter即可:
with localconverter(my_converter): pd_from_r_df = ro.conversion.rpy2py(res) print(pd_from_r_df)
转换后的正确输出:
int float chr bool 1 4 1.2 A True 2 <NA> NaN <NA> False
补充说明
该转换异常的本质是numpy原生的int、bool dtype不支持缺失值,rpy2内置的默认转换逻辑为了兼容1.0版本以前的pandas(无官方可空整数、布尔类型),才会使用整型最小值占位整型NA、将布尔值映射为0/1整数。上述自定义转换器基于pandas 1.0+版本提供的可空dtype实现,和R端的类型语义完全对齐。
- 该转换器完全兼容原有浮点、字符串类型的转换逻辑,不需要修改其他业务代码
- 如果需要处理R因子、日期、时间等其他特殊类型的转换,可以按照相同的写法,给对应R向量类型注册转换函数即可
内容的提问来源于stack exchange,提问作者Someone2
相关产品推荐
相关产品推荐

