我试图优化算法以减少内存使用量,并且我已将此特定操作确定为一个难点。
我有一个对称矩阵,沿着行的索引数组,以及沿着列的另一个索引数组(这只是我没有在行索引中选择的所有值)。我觉得我应该能够同时传递两个索引,但我发现自己被迫沿着一个轴选择然后另一个轴,这导致一些内存问题,因为我实际上并不需要返回的数组的副本,只是我从中计算的统计数据。这就是我要做的事情:
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是一个新数组而不是一个视图。我只需要这个数组用于一个操作,所以如果我可以在这里消除返回副本或者至少使新数组变小(即通过尊重第二个花哨的索引选择,而我做第一个而不是两个单独的花哨索引操作)这将是更可取的。
答案 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_