如何在NumPy数组中通过每隔n个元素采样来重排数组?
如何高效重排NumPy数组(按间隔n采样重排)
我希望通过每隔n个元素采样的方式重排NumPy数组,当前用循环拼接的方法可行,但想找无需拼接的更优解。现有实现如下:
import numpy as np arr = np.arange(10) print(arr) # 输出: [0 1 2 3 4 5 6 7 8 9] # 每隔5个元素采样重排 res = np.empty(shape=0) for i in range(5): res = np.concatenate([res, arr[i::5]]) print(res) # 输出: [0. 5. 1. 6. 2. 7. 3. 8. 4. 9.]
更高效的实现方案
方法1:reshape + 转置 + ravel(最简洁高效)
当数组长度能被n整除时,直接通过形状变换完成重排,全程矢量化操作,无内存重复分配:
n = 5 arr = np.arange(10) res = arr.reshape(-1, n).T.ravel() print(res) # 输出: [0 5 1 6 2 7 3 8 4 9]
如果数组长度无法被n整除,可先补全到整除长度,处理后再截断回原长度:
n = 5 arr = np.arange(11) # 长度11,无法被5整除 pad_length = (n - len(arr) % n) % n arr_padded = np.pad(arr, (0, pad_length), mode='constant') res = arr_padded.reshape(-1, n).T.ravel()[:len(arr)] print(res) # 输出: [0 5 10 1 6 2 7 3 8 4 9]
方法2:索引数组直接提取
通过生成目标索引序列,直接从原数组中提取元素,无需修改原数组形状,灵活性更高:
n = 5 arr = np.arange(10) indices = np.arange(len(arr)).reshape(-1, n).T.ravel() res = arr[indices] print(res) # 输出: [0 5 1 6 2 7 3 8 4 9]
针对长度不规整的数组,直接截断索引序列即可:
n = 5 arr = np.arange(11) indices = np.arange(len(arr)).reshape(-1, n).T.ravel()[:len(arr)] res = arr[indices] print(res) # 输出: [0 5 10 1 6 2 7 3 8 4 9]
方案对比
- 原循环拼接方案每次
concatenate都会重新分配内存,处理10000级元素时效率极低; - 上述两种方法均基于NumPy矢量化操作,速度能提升数倍至数十倍,且代码更符合Pythonic风格。
内容的提问来源于stack exchange,提问作者BoomBoxBoy
相关产品推荐
相关产品推荐

