如何修改Numpy ndarray中各列的数据类型?
解决Numpy数组多列类型转换的问题
普通Numpy ndarray是同构数组,所有元素共享同一数据类型,这就是你直接执行arr[:, 0] = arr[:, 0].astype(np.int64)却无效的原因——赋值时转换后的列会被强制转回原数组的dtype,等于白操作。要实现不同列用不同类型,必须将数组转换为结构化数组(structured array),它支持每列独立设置dtype,且内存开销远低于Pandas DataFrame。
具体实现步骤
方法1:通过dtype规格构造结构化数组
先定义每列的dtype规则,再将原数组转换为结构化数组:
import numpy as np import pickle # 从pickle读取原数组 with open("your_data.pkl", "rb") as f: arr = pickle.load(f) # 初始化所有列的dtype为原数组类型 dtype_spec = [(f"col{i}", arr.dtype) for i in range(arr.shape[1])] # 修改目标列的dtype dtype_spec[0] = ("col0", np.int64) dtype_spec[1] = ("col1", np.int8) dtype_spec[10] = ("col10", np.int16) dtype_spec[11] = ("col11", np.float64) # 转换为结构化数组 structured_arr = np.array([tuple(row) for row in arr], dtype=dtype_spec)
方法2:逐列转换后合并(更高效)
避免逐行转tuple,直接处理每列后构造结构化数组:
import numpy as np import pickle with open("your_data.pkl", "rb") as f: arr = pickle.load(f) # 逐列处理类型 cols = [] for idx in range(arr.shape[1]): col = arr[:, idx] if idx == 0: cols.append(col.astype(np.int64)) elif idx == 1: cols.append(col.astype(np.int8)) elif idx == 10: cols.append(col.astype(np.int16)) elif idx == 11: cols.append(col.astype(np.float64)) else: cols.append(col) # 构造结构化数组 structured_arr = np.rec.fromarrays(cols)
验证与使用
转换完成后,可通过以下方式验证列类型:
# 查看所有列的dtype print(structured_arr.dtype) # 访问指定列(两种方式都可行) col0_data = structured_arr["col0"] col1_data = structured_arr[:, 1]
结构化数组既保留了Numpy的高效计算特性,又通过精准设置列类型大幅降低了内存占用,完美替代Pandas DataFrame的类型转换场景。
内容的提问来源于stack exchange,提问作者luki
相关产品推荐
相关产品推荐

