为何rpy2转换后data.matrix会修改DataFrame数值?
问题根源
你遇到的数值异常问题,核心原因是把Pandas中的NaN替换成了字符串"NA",导致列类型从数值型变成了字符串型,进而触发了R的data.matrix()函数的特殊处理逻辑:
- 执行
df = df.replace(np.nan, "NA")后,原本的浮点数列被转换成字符串类型(Pandas的objectdtype)。 - rpy2将这个DataFrame转成R的DataFrame时,字符串列会被识别为R的
character向量。 - R的
data.matrix()处理字符型列时,会自动将其转为因子(factor),然后用因子的水平索引值(比如第一个唯一字符串对应1,第二个对应2,以此类推)填充矩阵——这就是你看到数值被“大幅修改”的本质,这些不是原始数值,是因子的编码值。 - 而你在R原生环境测试时,应该是直接导入了保留原生NaN的数值型DataFrame,
data.matrix()能正确识别数值列,将NaN转为R的NA,所以数值不会乱。
解决方案
去掉把NaN替换成字符串"NA"的步骤,保留Pandas原生的NaN,rpy2会自动将其映射为R的NA类型,data.matrix()就能正常处理数值列:
import pandas as pd import numpy as np import random import string import rpy2.robjects as ro from rpy2.robjects.packages import importr from rpy2.robjects import pandas2ri from rpy2.robjects.conversion import localconverter pandas2ri.activate() utils = importr('utils') # 生成随机列名的函数 def generate_column_names(n, suffixes): columns = [] for _ in range(n): name = ''.join(random.choices(string.ascii_uppercase, k=3)) suffix = random.choice(suffixes) columns.append(name + suffix) return columns n_rows = 1000 n_cols = 15 # 生成0-10的随机浮点数 data = np.random.uniform(0, 10, size=(n_rows, n_cols)) # 随机插入NaN nan_indices = np.random.choice([True, False], size=data.shape, p=[0.1, 0.9]) data[nan_indices] = np.nan column_names = generate_column_names(n_cols, ["_Healthy", "_Sick"]) # 创建DataFrame,保留原生NaN df = pd.DataFrame(data, columns=column_names) # 移除错误的字符串替换步骤 # df = df.replace(np.nan, "NA") with localconverter(ro.default_converter + pandas2ri.converter): R_df = ro.conversion.py2rpy(df) r_matrix = ro.r('data.matrix')(R_df)
补充说明
如果确实需要处理缺失值,一定要保持列的数值类型:
- 可以用数值填充,比如
df.fillna(0)或df.fillna(df.mean()) - 绝对不要将NaN替换成字符串,这会彻底改变列的数据类型,引发后续R处理的异常
内容的提问来源于stack exchange,提问作者Bob McBobson
相关产品推荐
相关产品推荐

