基于 2d numpy 数组中的索引列表访问行的更有效方法?
More efficient way to access rows based on a list of indices in 2d numpy array?
所以我有 2d numpay 数组 arr。比较大的一个:arr.shape = (2400, 60000)
我目前正在做的是:
- 随机(有替换)select
arr.shape[0]
索引
- 访问(按行)选择的
arr
索引
- 计算列平均值和select计算最大值
- 我要重复k次
它看起来像:
no_rows = arr.shape[0]
indicies = np.array(range(no_rows))
my_vals = []
for k in range(no_samples):
random_idxs = np.random.choice(indicies, size=no_rows, replace=True)
my_vals.append(
arr[random_idxs].mean(axis=0).max()
)
我的问题是速度很慢。使用我的 arr
尺寸,1 个循环需要 ~3 秒。因为我想要一个大于 1k 的样本 - 我当前的解决方案非常糟糕(1k*~3s -> ~1h)。我已经对它进行了分析,瓶颈是基于索引访问行。 "mean"
和"max"
工作fast. np.random.choice
也可以。
您认为有任何需要改进的地方吗?一种更有效的访问索引的方法,或者更好的方法,可以在没有这个的情况下解决问题?
到目前为止我尝试了什么:
- numpy.take(较慢)
- numpy.ravel :
类似于:
random_idxs = np.random.choice(sample_idxs, size=sample_size, replace=True)
test = random_idxs.ravel()[arr.ravel()].reshape(arr.shape)
- 与当前方法类似但没有循环。我创建了 3d arr 并一次性访问了额外维度的行
这不是问题的通用解决方案,但应该可以使您的特定问题更快。基本上,arr.mean(axis=0).max()
不会改变,那么为什么不从该数组中随机抽样呢?
类似于:
mean_max = arr.mean(axis=0).max()
my_vals = np.array([np.random.choice(mean_max, size=len(mean_max), replace=True) for i in range(no_samples)])
您甚至可以做到:my_vals = np.random.choice(mean_max, size=(no_samples, len(mean_max)), replace=True)
,但我不确定这会如何改变您的统计数据。
由于advanced indexing会生成一个副本,程序会在arr[random_idxs]
分配大量内存。
因此,提高效率的最简单方法之一就是批量处理。
BATCH = 512
max(arr[random_idxs,i:i+BATCH].mean(axis=0).max() for i in range(0,arr.shape[1],BATCH))
所以我有 2d numpay 数组 arr。比较大的一个:arr.shape = (2400, 60000)
我目前正在做的是:
- 随机(有替换)select
arr.shape[0]
索引 - 访问(按行)选择的
arr
索引
- 计算列平均值和select计算最大值
- 我要重复k次
它看起来像:
no_rows = arr.shape[0]
indicies = np.array(range(no_rows))
my_vals = []
for k in range(no_samples):
random_idxs = np.random.choice(indicies, size=no_rows, replace=True)
my_vals.append(
arr[random_idxs].mean(axis=0).max()
)
我的问题是速度很慢。使用我的 arr
尺寸,1 个循环需要 ~3 秒。因为我想要一个大于 1k 的样本 - 我当前的解决方案非常糟糕(1k*~3s -> ~1h)。我已经对它进行了分析,瓶颈是基于索引访问行。 "mean"
和"max"
工作fast. np.random.choice
也可以。
您认为有任何需要改进的地方吗?一种更有效的访问索引的方法,或者更好的方法,可以在没有这个的情况下解决问题?
到目前为止我尝试了什么:
- numpy.take(较慢)
- numpy.ravel :
类似于:
random_idxs = np.random.choice(sample_idxs, size=sample_size, replace=True)
test = random_idxs.ravel()[arr.ravel()].reshape(arr.shape)
- 与当前方法类似但没有循环。我创建了 3d arr 并一次性访问了额外维度的行
这不是问题的通用解决方案,但应该可以使您的特定问题更快。基本上,arr.mean(axis=0).max()
不会改变,那么为什么不从该数组中随机抽样呢?
类似于:
mean_max = arr.mean(axis=0).max()
my_vals = np.array([np.random.choice(mean_max, size=len(mean_max), replace=True) for i in range(no_samples)])
您甚至可以做到:my_vals = np.random.choice(mean_max, size=(no_samples, len(mean_max)), replace=True)
,但我不确定这会如何改变您的统计数据。
由于advanced indexing会生成一个副本,程序会在arr[random_idxs]
分配大量内存。
因此,提高效率的最简单方法之一就是批量处理。
BATCH = 512
max(arr[random_idxs,i:i+BATCH].mean(axis=0).max() for i in range(0,arr.shape[1],BATCH))