花式索引沿多个轴的numpy数组的最佳实践

时间:2014-10-30 21:07:29

标签: python arrays numpy indexing

我试图优化算法以减少内存使用量,并且我已将此特定操作确定为一个难点。

我有一个对称矩阵,沿着行的索引数组,以及沿着列的另一个索引数组(这只是我没有在行索引中选择的所有值)。我觉得我应该能够同时传递两个索引,但我发现自己被迫沿着一个轴选择然后另一个轴,这导致一些内存问题,因为我实际上并不需要返回的数组的副本,只是我从中计算的统计数据。这就是我要做的事情:

from scipy.spatial.distance import pdist, squareform
from sklearn import datasets
import numpy as np

iris = datasets.load_iris().data

dx = pdist(iris)
mat = squareform(dx)

outliers = [41,62,106,108,109,134,135]
inliers = np.setdiff1d( range(iris.shape[0]), outliers)

# What I want to be able to do:
scores = mat[inliers, outliers].min(axis=0)

以下是我实际做的工作:

# What I'm being forced to do:
s1 = mat[:,outliers]
scores = s1[inliers,:].min(axis=0)

因为我喜欢索引,所以s1是一个新数组而不是一个视图。我只需要这个数组用于一个操作,所以如果我可以在这里消除返回副本或者至少使新数组变小(即通过尊重第二个花哨的索引选择,而我做第一个而不是两个单独的花哨索引操作)这将是更可取的。

3 个答案:

答案 0 :(得分:5)

“广播”适用于索引。您可以将inliers转换为列矩阵(例如inliers.reshape(-1,1)inliers[:, np.newaxis],因此它具有形状(m,1))和索引mat,并将其转换为第一列: / p>

s1 = mat[inliers.reshape(-1,1), outliers]
scores = s1.min(axis=0)

答案 1 :(得分:1)

尝试:

outliers = np.array(outliers)  # just to be sure they are arrays
result = mat[inliers[:, np.newaxis], outliers[np.newaxis, :]].min(0)

答案 2 :(得分:1)

在可读性方面有更好的方法:

result = mat[np.ix_(inliers, outliers)].min(0)

https://docs.scipy.org/doc/numpy/reference/generated/numpy.ix_.html#numpy.ix_