如何防止numpy.select强制转换choicelist与default参数值类型
问题根因
np.select未指定输出数组时,会自动根据所有待选值、默认值的类型推断输出数组dtype。在numpy 1.21.x版本的类型推断逻辑中,只要待选值里存在字符串类型,就会将输出数组dtype设为固定长度字符串类型,所有元素(包括传入的np.NaN)都会被强制转换为字符串,因此才会出现np.NaN变成字符串'nan'、数值被转成字符串的问题。
提前将待选列表转为object dtype数组无法解决问题,因为类型推断是np.select内部执行的,不会因为输入的choicelist是object类型就默认输出object数组。
解决方案
不需要重写np.select逻辑,两种无补丁的正规实现方式如下:
方式1:指定out参数(改动最小,贴合原有写法)
np.select支持numpy通用的out参数,提前创建好dtype为object的输出数组、预填充np.NaN,将其传入np.select即可跳过内部的自动类型推断,保留所有元素的原始类型:
import numpy as np import pandas as pd series1 = pd.Series([True, False, False]) series2 = pd.Series([True, True, False]) list_of_series = [series1, series2] list_of_values = ['1', '2'] # 提前初始化object类型输出数组,默认值填充np.NaN out_arr = np.full(len(series1), np.NaN, dtype=object) np.select(list_of_series, list_of_values, default=np.NaN, out=out_arr) result = pd.Series(out_arr) print(result.unique()) # 输出:['1' '2' nan],符合预期
方式2:pandas原生逐条件赋值(最适配pandas场景)
直接初始化全为np.NaN的object类型Series,遍历条件和对应值逐次赋值,完全绕开numpy的类型推断逻辑,代码可读性更高,还能自动对齐Series索引避免错位:
# 初始化结果Series,和输入索引保持一致 result = pd.Series(np.NaN, index=series1.index, dtype=object) for cond, val in zip(list_of_series, list_of_values): result.loc[cond] = val
内容的提问来源于stack exchange,提问作者Uretki
相关产品推荐
相关产品推荐

