为什么numpy没有对应‘is’操作的ufunc?有什么高性能替代方案?
为什么numpy没有推出对应
is操作的ufunc is操作的核心语义是判断两个对象是否为内存中的同一个实例,仅适用于Python对象的引用比较,而numpy的ufunc体系主要面向数值型数组的向量化运算,通用is ufunc的使用场景极其有限,仅在判断None、True、False这类全局单例时会用到,普通数值运算场景完全不需要。其次numpy团队此前评估过相关需求,认为is和==语义容易被普通用户混淆,引入后会大幅提升误用概率,维护成本远高于实际收益,因此没有单独推出通用的is ufunc。
高性能替代方案
按使用场景可以选择对应的实现方案,性能均远高于Python层的列表推导遍历:
- 场景1:仅需要判断元素是否为None(最常见需求)
如果使用numpy 1.24及以上版本,直接用官方原生的np.isnoneufunc,性能最高,无Python层开销:
如果版本低于1.24,用a[np.isnone(a)] = somethingnp.frompyfunc自定义ufunc,性能比Python层遍历高3~8倍:
如果项目中已引入pandas,可直接使用优化过的# 生成判断是否为None的自定义ufunc,输入1个参数,输出1个结果 is_none_ufunc = np.frompyfunc(lambda x: x is None, 1, 1) a[is_none_ufunc(a).astype(bool)] = somethingpd.isna,同时兼容None、NaN等空值判断,性能也优于自行实现的方案:import pandas as pd a[pd.isna(a)] = something - 场景2:判断元素是否为任意指定的单例对象
直接修改np.frompyfunc的判断逻辑即可,比如要判断元素是否和全局对象custom_singleton为同一个实例:is_target = np.frompyfunc(lambda x: x is custom_singleton, 1, 1)(a).astype(bool) a[is_target] = something
内容的提问来源于stack exchange,提问作者Bubaya
相关产品推荐
相关产品推荐

