Python如何通过索引无循环拆分多维NumPy数组为两个单列数组
NumPy数组无循环拆分方案
问题背景
待处理的输入是存储了多个形状为(1,2)的float32类型NumPy数组的列表,样例结构如下:
[ array([[55. , 0.2443461]], dtype=float32), array([[-51. , 2.8972466]], dtype=float32), array([[-10. , 2.8972466]], dtype=float32), array([[221. , 0.2268928]], dtype=float32), array([[2.2000000e+02, 2.0943952e-01]], dtype=float32) ]
需要将其拆分为两个独立数组:
- 第一个数组收集所有子数组的第一个元素,预期结果为
[55, -51, -10, 221, 220](注:示例中写的1.2000000e+02为笔误,原输入最后一个子数组首值为2.2e+02即220) - 第二个数组收集所有子数组的第二个元素,预期结果为
[0.2443461, 2.8972466, 2.8972466, 0.2268928, 2.0943952e-01]
原有实现为Python层显式循环,大数据量下效率较低:
for x in range(lines_len): lines_angles.append(lines[x][0][1]) lines_dist.append(lines[x][0][0])
无循环实现方法
可以完全通过NumPy原生向量化操作实现,避免Python层循环,执行效率会有量级提升,仅需两步:
- 用
np.vstack将列表中所有零散的(1,2)子数组纵向堆叠为一个形状为(N, 2)的统一二维数组,N为子数组总个数 - 直接通过列索引拆分二维数组即可,第0列对应所有首元素,第1列对应所有次元素
完整代码:
import numpy as np # 合并为统一二维数组 lines_merged = np.vstack(lines) # 按列拆分 lines_dist = lines_merged[:, 0] lines_angles = lines_merged[:, 1]
如果需要输出Python原生列表而非NumPy数组,只需要调用.tolist()方法即可:
lines_dist = lines_merged[:, 0].tolist() lines_angles = lines_merged[:, 1].tolist()
效果验证
执行后输出结果与预期完全匹配:
lines_dist: [ 55. -51. -10. 221. 220.] lines_angles: [0.2443461 2.8972466 2.8972466 0.2268928 0.20943952]
内容的提问来源于stack exchange,提问作者BranAndSceolan
相关产品推荐
相关产品推荐

