如何追加混合元素类型numpy数组?过滤时IndexError错误求解
问题1:如何将混合元素类型的numpy数组追加到另一个数组中?
处理混合类型的numpy数组时,直接用普通np.append很容易踩坑——numpy默认会强制统一元素类型,要么丢数据要么报错。给你两个实用的解决方案:
方案一:用结构化数组(推荐,效率高)
结构化数组允许你给每个字段指定不同类型,天生适合存混合类型数据。比如你要存字符串ID和数值,先定义好dtype再操作:import numpy as np # 定义字段类型:id是字符串,value是浮点数 dtype_def = [('id', 'U10'), ('value', float)] # 初始化第一个数组 arr1 = np.array([('A1', 1.5), ('A2', 2.3)], dtype=dtype_def) # 要追加的新元素 new_entry = np.array([('A3', 3.7)], dtype=dtype_def) # 完成追加 combined_arr = np.append(arr1, new_entry)方案二:用object类型数组(快速原型用)
如果不想麻烦定义dtype,可以把数组设为object类型,这样能容纳任意类型元素,缺点是运算效率稍低:arr1 = np.array([('A1', 1.5), ('A2', 2.3)], dtype=object) new_entry = np.array([('A3', 3.7)], dtype=object) combined_arr = np.append(arr1, new_entry)
问题2:修复过滤数组时的IndexError错误
咱们先拆解你代码里的几个问题:
- NaN判断完全错了:
i.any == 'nan'是语法错误,i.any()是方法不是属性,而且判断NaN得用np.isnan(),但你的数组是混合类型,不能直接对整个元素用这个函数,得针对数值字段判断; np.delete用法不对:np.delete(stacked[i])参数完全错了,它需要数组+要删除的索引,而且np.delete不会修改原数组,是返回新数组,这么写根本删不了元素;np.append的坑:初始化空数组filtered_array = np.array([])的dtype是float,你要追加混合类型元素肯定出问题,而且循环里反复用np.append效率极低(每次都要创建新数组);astype白调用了:ID.astype(str)不会修改原数组,得赋值回去,比如ID = ID.astype(str)。
下面是修正后的高效代码,用numpy原生的布尔索引过滤,比循环快太多:
from astropy.table import Table import numpy as np data = '/home/myname/data.fits' data = Table.read(data, format="fits") # 修正astype:必须赋值回去才生效 ID = np.array(data['id']).astype(str) redshift = np.array(data['z']).astype(float) radius = np.array(data['r']).astype(float) mag = np.array(data['magnitude']).astype(float) # 改用结构化数组存储混合类型,比列表推导式更规范高效 stacked = np.core.records.fromarrays( [ID, redshift, radius, mag], dtype=[('id', 'U20'), ('z', float), ('r', float), ('magnitude', float)] ) # 生成过滤掩码:只要数值字段有一个是NaN就过滤掉该行 # ~是取反,保留所有数值都非NaN的行 filter_mask = ~(np.isnan(stacked['z']) | np.isnan(stacked['r']) | np.isnan(stacked['magnitude'])) filtered_array = stacked[filter_mask]
如果你非要用循环(不推荐,数据量大时很慢),可以这么改:
# 先用列表存结果,列表追加比np.append高效多了 filtered_list = [] for item in stacked: # 检查三个数值字段是否都不是NaN if not np.isnan(item[1]) and not np.isnan(item[2]) and not np.isnan(item[3]): filtered_list.append(item) # 最后转成numpy数组,复用原数组的dtype filtered_array = np.array(filtered_list, dtype=stacked.dtype)
这样既解决了IndexError,又保证了混合类型数据的正确存储,还提高了效率。
内容的提问来源于stack exchange,提问作者yikesthisisamess
相关产品推荐
相关产品推荐

