访问数组中的多个元素 [英] Access multiple elements of an array

查看:151
本文介绍了访问数组中的多个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法让一个操作数组元素这些元素的知行和列?在每一行,我想从col_start访问元素col_end(每行有不同的起始和结束索引)。元件的数目为每一行的相同,单元是连续的。
例如:

  [。 。 。 。 | | | 。 。 。 。 。 ]
[| | | 。 。 。 。 。 。 。 。 。 ]
[。 。 | | | 。 。 。 。 。 。 。 ]
[。 。 。 。 。 。 。 。 | | | 。 ]

一个解决方案是获得元件的索引(行 - 列对),并且比使用my_array [row_list,col_list]。

是否有任何其他(简单)的方式,而不使用循环?


解决方案

  A = np.arange(40).reshape(4,10)* 1
startend = [[2,5],[3,6],[4,7],[5,8]
index_list = [np.arange(ⅴ[0],V [1])+ I * A.shape [1]
                 对于I,V在历数(startend)
#[阵列([2,3,4]),阵列([13,14,15]),阵列([24,25,26]),阵列([35,36,37])]
A.flat [index_list]

生产

 阵列([0.2,0.3,0.4]
       [1.3,1.4,1.5],
       [2.4,2.5,2.6],
       [3.5,3.6,3.7])

这还是有一个迭代,但它是在一个列表上一个相当基本的。
我索引夷为平地,1D,版本 A 的。 np.take(A,index_list)也能工作。

如果该行间隔大小不同,我可以使用 np.r _ 将它们串联。这不是绝对必要的,但是建立多个区间和值指标时,它是一个方便的。

  A.flat [np.r_ [元组(index_list)]
#阵列([0.2,0.3,0.4,1.3,1.4,1.5,2.4,2.5,2.6,3.5,3.6,3.7])


IDX ajcr 使用未经中选择

  IDX = [np.arange(V [0],V [1])为I,V在历数(startend)
A [np.arange(A.shape [0]):,无],IDX]

IDX 就像是我的 index_list 但它不会增加该行的长度。

  np.array(IDX)阵列([[2,3,4],
       [3,4,5],
       [4,5,6]中
       [5,6,7]])

由于每个人气指数具有相同的长度,可以不重复生成 IDX

  col_start = np.array([2,3,4,5])
IDX = col_start [:,无] + np.arange(3)

第一个指标是广播匹配列数组这个 IDX

  np.arange(A.shape [0]):,无]
阵列([[0],
       [1],
       [2],
       [3]])

有了这个 A IDX 我得到以下计时:

 在[515]:timeit np.choose(IDX,A.T [:,:,无])
10000循环,最好的3:每圈30.8微秒在[516]:timeit A [np.arange(A.shape [0]):,无],IDX]
100000循环,最好的3:每圈10.8微秒在[517]:timeit A.flat [IDX + np.arange(A.shape [0])[:,无] * A.shape [1]]
10000循环,最好的3:每圈24.9微秒

索引速度较快,但计算票友指数占用一定的时间。

有关大型阵列,索引的速度主宰。

  A = np.arange(4000).reshape(40,100)* 1
col_start = np.arange(20,60)
IDX = col_start [:,无] + np.arange(30)在[536]:timeit A [np.arange(A.shape [0]):,无],IDX]
10000循环,最好的3:每回路108微秒在[537]:timeit A.flat [IDX + np.arange(A.shape [0])[:,无] * A.shape [1]]
10000循环,最好的3:每圈59.4微秒

np.choose 方法运行成硬codeD限制: 2(32)数组对象(含)之间的需要。


什么出界 IDX

  col_start = np.array([2,4,6,8])
IDX = col_start [:,无] + np.arange(3)
A [np.arange(A.shape [0]):,无],IDX]

因为最后 IDX 值是产生一个错误 10 ,太大了。

您可以片段 IDX

  IDX = idx.clip(0,A.shape [1] -1)

的最后一行中产生重复的值

  3.8,3.9,3.9]

您在索引之前还可以垫 A 。参见 np.pad 更多选项。

  np.pad(A,((0,0),(0,2)),边缘)np.arange(A.shape [0]): ,无],IDX]

另一种选择是去除超出边界的值。 IDX 然后将成为列表的一个衣衫褴褛的列表(或数组列表)。在办法可以处理这一点,虽然结果将不会是一个矩阵。

  startend = [[2,5],[4,7],[6,9],[8,10]
index_list = [np.arange(ⅴ[0],V [1])+ I * A.shape [1]
                 对于I,V在历数(startend)
#[阵列([2,3,4]),阵列([14,15,16]),阵列([26,27,28]),阵列([38,39])]A.flat [np.r_ [元组(index_list)]
#阵列([0.2,0.3,0.4,1.4,1.5,1.6,2.6,2.7,2.8,3.8,3.9])

Is there a way to get array elements in one operation for known rows and columns of those elements? In each row I would like to access elements from col_start to col_end (each row has different starting and ending index). Number of elements is the same for each row, elements are consecutive. Example:

[ . . . . | | | . . . . . ]
[ | | | . . . . . . . . . ]
[ . . | | | . . . . . . . ]
[ . . . . . . . . | | | . ]

One solution would be to get indexes (row-column pair) of elements, and than use my_array[row_list,col_list].

Is there any other (simpler) way without using for loops?

解决方案

A = np.arange(40).reshape(4,10)*.1
startend = [[2,5],[3,6],[4,7],[5,8]]
index_list = [np.arange(v[0],v[1]) + i*A.shape[1] 
                 for i,v in enumerate(startend)]
# [array([2, 3, 4]), array([13, 14, 15]), array([24, 25, 26]), array([35, 36, 37])]
A.flat[index_list]

producing

array([[ 0.2,  0.3,  0.4],
       [ 1.3,  1.4,  1.5],
       [ 2.4,  2.5,  2.6],
       [ 3.5,  3.6,  3.7]])

This still has an iteration, but it's a rather basic one over a list. I'm indexing the flattened, 1d, version of A. np.take(A, index_list) also works.

If the row intervals differ in size, I can use np.r_ to concatenate them. It's not absolutely necessary, but it is a convenience when building up indices from multiple intervals and values.

A.flat[np.r_[tuple(index_list)]]
# array([ 0.2,  0.3,  0.4,  1.3,  1.4,  1.5,  2.4,  2.5,  2.6,  3.5,  3.6, 3.7])


The idx that ajcr uses can be used without choose:

idx = [np.arange(v[0], v[1]) for i,v in enumerate(startend)]
A[np.arange(A.shape[0])[:,None], idx]

idx is like my index_list except that it doesn't add the row length.

np.array(idx)

array([[2, 3, 4],
       [3, 4, 5],
       [4, 5, 6],
       [5, 6, 7]])

Since each arange has the same length, idx can be generated without iteration:

col_start = np.array([2,3,4,5])
idx = col_start[:,None] + np.arange(3)

The first index is a column array that broadcasts to match this idx.

np.arange(A.shape[0])[:,None] 
array([[0],
       [1],
       [2],
       [3]])

With this A and idx I get the following timings:

In [515]: timeit np.choose(idx,A.T[:,:,None])
10000 loops, best of 3: 30.8 µs per loop

In [516]: timeit A[np.arange(A.shape[0])[:,None],idx]
100000 loops, best of 3: 10.8 µs per loop

In [517]: timeit A.flat[idx+np.arange(A.shape[0])[:,None]*A.shape[1]]
10000 loops, best of 3: 24.9 µs per loop

The flat indexing is faster, but calculating the fancier index takes up some time.

For large arrays, the speed of flat indexing dominates.

A=np.arange(4000).reshape(40,100)*.1
col_start=np.arange(20,60)
idx=col_start[:,None]+np.arange(30)

In [536]: timeit A[np.arange(A.shape[0])[:,None],idx]
10000 loops, best of 3: 108 µs per loop

In [537]: timeit A.flat[idx+np.arange(A.shape[0])[:,None]*A.shape[1]]
10000 loops, best of 3: 59.4 µs per loop

The np.choose method runs into a hardcoded limit: Need between 2 and (32) array objects (inclusive).


What out of bounds idx?

col_start=np.array([2,4,6,8])
idx=col_start[:,None]+np.arange(3)
A[np.arange(A.shape[0])[:,None], idx]

produces an error because the last idx value is 10, too large.

You could clip idx

idx=idx.clip(0,A.shape[1]-1)

producing duplicate values in the last row

[ 3.8,  3.9,  3.9]

You could also pad A before indexing. See np.pad for more options.

np.pad(A,((0,0),(0,2)),'edge')[np.arange(A.shape[0])[:,None], idx]

Another option is to remove out of bounds values. idx would then become a ragged list of lists (or array of lists). The flat approach can handle this, though the result will not be a matrix.

startend = [[2,5],[4,7],[6,9],[8,10]]
index_list = [np.arange(v[0],v[1]) + i*A.shape[1] 
                 for i,v in enumerate(startend)]
# [array([2, 3, 4]), array([14, 15, 16]), array([26, 27, 28]), array([38, 39])]

A.flat[np.r_[tuple(index_list)]]
# array([ 0.2,  0.3,  0.4,  1.4,  1.5,  1.6,  2.6,  2.7,  2.8,  3.8,  3.9])

这篇关于访问数组中的多个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆