NumPy 使用索引列表选择每行的特定列索引

2025-01-15 08:45:00
admin
原创
159
摘要:问题描述:我正在努力选择 NumPy 矩阵每行的特定列。假设我有以下矩阵,我将其称为X:[1, 2, 3] [4, 5, 6] [7, 8, 9] 我list每行都有一个列索引,我称之为Y:[1, 0, 2] 我需要获取以下值:[2] [4] [9] 除了带有list索引的以外Y,我还可以生成一个具有相同形状...

问题描述:

我正在努力选择 NumPy 矩阵每行的特定列。

假设我有以下矩阵,我将其称为X

[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

list每行都有一个列索引,我称之为Y

[1, 0, 2]

我需要获取以下值:

[2]
[4]
[9]

除了带有list索引的以外Y,我还可以生成一个具有相同形状的矩阵,X其中每一列都是一个介于 0-1 值之间的bool/ ,表示这是否是所需的列。int

[0, 1, 0]
[1, 0, 0]
[0, 0, 1]

我知道这可以通过迭代数组并选择我需要的列值来完成。但是,这将在大数据数组上频繁执行,这就是为什么它必须尽可能快地运行。

因此我想知道是否有更好的解决方案?


解决方案 1:

如果您有一个布尔数组,您可以根据该数组进行直接选择,如下所示:

>>> a = np.array([True, True, True, False, False])
>>> b = np.array([1,2,3,4,5])
>>> b[a]
array([1, 2, 3])

为了配合您最初的例子,您可以执行以下操作:

>>> a = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> b = np.array([[False,True,False],[True,False,False],[False,False,True]])
>>> a[b]
array([2, 4, 9])

您还可以添加arange并直接选择,但这取决于您如何生成布尔数组以及您的代码是什么样子的 YMMV。

>>> a = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> a[np.arange(len(a)), [1,0,2]]
array([2, 4, 9])

解决方案 2:

你可以做这样的事情:

In [7]: a = np.array([[1, 2, 3],
   ...: [4, 5, 6],
   ...: [7, 8, 9]])

In [8]: lst = [1, 0, 2]

In [9]: a[np.arange(len(a)), lst]
Out[9]: array([2, 4, 9])

有关索引多维数组的更多信息:http://docs.scipy.org/doc/numpy/user/basics.indexing.html#indexing-multi-Dimension-arrays

解决方案 3:

最近的numpy版本添加了一个take_along_axis(和put_along_axis),可以干净地完成索引。

In [101]: a = np.arange(1,10).reshape(3,3)                                                             
In [102]: b = np.array([1,0,2])                                                                        
In [103]: np.take_along_axis(a, b[:,None], axis=1)                                                     
Out[103]: 
array([[2],
       [4],
       [9]])

其运作方式与以下相同:

In [104]: a[np.arange(3), b]                                                                           
Out[104]: array([2, 4, 9])

argsort但轴处理方式不同。它特别适用于应用和的结果argmax

解决方案 4:

一个简单的方法可能是这样的:

In [1]: a = np.array([[1, 2, 3],
   ...: [4, 5, 6],
   ...: [7, 8, 9]])

In [2]: y = [1, 0, 2]  #list of indices we want to select from matrix 'a'

range(a.shape[0])将会回归array([0, 1, 2])

In [3]: a[range(a.shape[0]), y] #we're selecting y indices from every row
Out[3]: array([2, 4, 9])

解决方案 5:

你可以使用迭代器来实现。像这样:

np.fromiter((row[index] for row, index in zip(X, Y)), dtype=int)

时间:

N = 1000
X = np.zeros(shape=(N, N))
Y = np.arange(N)

#@Aशwini चhaudhary
%timeit X[np.arange(len(X)), Y]
10000 loops, best of 3: 30.7 us per loop

#mine
%timeit np.fromiter((row[index] for row, index in zip(X, Y)), dtype=int)
1000 loops, best of 3: 1.15 ms per loop

#mine
%timeit np.diag(X.T[Y])
10 loops, best of 3: 20.8 ms per loop

解决方案 6:

hpaulj 使用 take_along_axis 给出的答案应该是可以接受的。

这是一个具有 N 维索引数组的派生版本:

>>> arr = np.arange(20).reshape((2,2,5))
>>> idx = np.array([[1,0],[2,4]])
>>> np.take_along_axis(arr, idx[...,None], axis=-1)
array([[[ 1],
        [ 5]],

       [[12],
        [19]]])

请注意,选择操作与形状无关。我用它来通过拟合抛物线来改进可能的矢量值argmax结果:histogram

def interpol(arr):
    i = np.argmax(arr, axis=-1)
    a = lambda Δ: np.squeeze(np.take_along_axis(arr, i[...,None]+Δ, axis=-1), axis=-1)
    frac = .5*(a(1) - a(-1)) / (2*a(0) - a(-1) - a(1)) # |frac| < 0.5
    return i + frac

注意,squeeze删除大小为 1 的维度,从而得到相同形状的ifrac,即峰值位置的整数和小数部分。

我很确定可以避免lambda,但插值公式看起来仍然不错吗?

解决方案 7:

另一个巧妙的方法是先转置数组,然后对其进行索引。最后取对角线,这总是正确的答案。

X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
Y = np.array([1, 0, 2, 2])

np.diag(X.T[Y])

步步:

原始数组:

>>> X
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]])

>>> Y
array([1, 0, 2, 2])

转置以便能够正确索引。

>>> X.T
array([[ 1,  4,  7, 10],
       [ 2,  5,  8, 11],
       [ 3,  6,  9, 12]])

按 Y 顺序获取行。

>>> X.T[Y]
array([[ 2,  5,  8, 11],
       [ 1,  4,  7, 10],
       [ 3,  6,  9, 12],
       [ 3,  6,  9, 12]])

对角线现在应该变得清晰了。

>>> np.diag(X.T[Y])
array([ 2,  4,  9, 12]
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1553  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   27  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   22  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   19  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用