Python - 如何使用其他numpy数组正确索引numpy数组,类似于MATLAB

时间:2017-03-22 20:38:06

标签: python arrays matlab numpy indexing

我正在尝试使用MATLAB多年来学习python,这是我真正坚持的事情。我有一个数组,比如10比8.我希望在第一列中找到值为3的行,并在该行中使用“2:”列。我所做的是:

newArray = oldArray[np.asarray(np.where(oldArray[:,0] == 3)), 2:]

但是这会创建一个第一维1而不是二维数组的三维数组。我正在尝试实现MATLAB等效的

newArray = oldArray(find(oldArray(:,1)==3),3:end);

有人对如何做到这一点有任何想法吗?谢谢!

1 个答案:

答案 0 :(得分:2)

Slice第一列并与3进行比较,为我们提供选择行的掩码。通过索引到输入数组的2D数组的第一个轴/行来选择行之后,我们需要选择列(数组的第二个轴)。在您的MATLAB代码中,您有3:end,它将在NumPy上转换为2:。在MATLAB中,您需要在NumPy中指定结束索引。因此,与MATLAB上的2:相比,它简化为3:end

因此,代码将是 -

oldArray[oldArray[:,0]==3,2:]

示例运行 -

In [352]: a
Out[352]:    |===============>|
array([[1, 0, 4, 2, 0, 1, 3, 2],
       [1, 0, 0, 3, 2, 3, 4, 4],
       [1, 2, 1, 4, 4, 0, 4, 2],
       [0, 2, 0, 3, 2, 2, 1, 2],
       [1, 2, 3, 3, 1, 0, 0, 1],
       [3, 4, 2, 4, 2, 0, 3, 4],  <==
       [3, 1, 1, 0, 0, 1, 2, 0],  <==
       [2, 0, 4, 3, 1, 3, 1, 1],
       [4, 3, 1, 3, 1, 3, 4, 4],
       [2, 0, 2, 0, 3, 1, 1, 1]])

In [353]: a[a[:,0]==3,2:]
Out[353]: 
array([[2, 4, 2, 0, 3, 4],
       [1, 0, 0, 1, 2, 0]])

查看您的代码 -

您的代码是 -

In [359]: a[np.asarray(np.where(a[:,0] == 3)), 2:]
Out[359]: 
array([[[2, 4, 2, 0, 3, 4],
        [1, 0, 0, 1, 2, 0]]])

也可以,但会创建问题中列出的3D数组。

解剖 -

In [361]: np.where(a[:,0] == 3)
Out[361]: (array([5, 6]),)

我们看到np.where是一个数组元组,它是行和列索引。对于1D的切片,您不会同时拥有行和列,但是 只是一个索引数组。

在MATLAB中,find为您提供了一系列索引,因此不会产生混淆 -

>> a
a =
     3     4     3     3
     2     5     5     2
     2     2     2     3
     5     3     4     4
     4     3     4     2
     3     2     4     2
>> find(a(:,1)==3)
ans =
     1
     6

因此,要获得这些索引,请从中获取第一个数组 -

In [362]: np.where(a[:,0] == 3)[0]
Out[362]: array([5, 6])

使用它来索引第一个轴,然后从2开始对列进行切片 -

In [363]: a[np.where(a[:,0] == 3)[0]]
Out[363]: 
array([[3, 4, 2, 4, 2, 0, 3, 4],
       [3, 1, 1, 0, 0, 1, 2, 0]])

In [364]: a[np.where(a[:,0] == 3)[0],2:]
Out[364]: 
array([[2, 4, 2, 0, 3, 4],
       [1, 0, 0, 1, 2, 0]])

这可以为您提供预期的输出。

谨慎提示

在使用掩码或整数索引到轴时需要小心。

理论上,列索引应该等同于[2,3,4,5,6,7] a 8 columns的索引。

试试吧 -

In [370]: a[a[:,0]==3,[2,3,4,5,6,7]]
....
IndexError: shape mismatch: indexing arrays could ...
     not be broadcast together with shapes (2,) (6,) 

我们正在触发 broadcastable 索引。索引到两个轴的元素长度不同,不能播放。

让我们验证一下。用于索引到rows -

的数组
In [374]: a[:,0]==3
Out[374]: array([False, False, False, False, False,  True,  True, False, False, False], dtype=bool)

基本上这是两个元素的数组,因为有两个True元素 -

In [375]: np.where(a[:,0]==3)[0]
Out[375]: array([5, 6])

用于索引到列的数组是[2,3,4,5,6,7],其长度为6,因此无法针对行索引进行广播。

要达到我们所需的选择行ID的目标:5,6,并为每个行选择列ID 2,3,4,5,6,7,我们可以使用np._ix创建open meshes可播放的,像这样 -

In [376]: np.ix_(a[:,0]==3, [2,3,4,5,6,7])
Out[376]: 
(array([[5],
        [6]]), array([[2, 3, 4, 5, 6, 7]]))

最后,使用所需o / p -

的索引输入数组
In [377]: a[np.ix_(a[:,0]==3, [2,3,4,5,6,7])]
Out[377]: 
array([[2, 4, 2, 0, 3, 4],
       [1, 0, 0, 1, 2, 0]])