gpt4 book ai didi

python - 有效地选择 numpy 数组的子部分

转载 作者:太空宇宙 更新时间:2023-11-03 18:08:12 24 4
gpt4 key购买 nike

我想根据逻辑比较将 numpy 数组拆分为三个不同的数组。我想要拆分的 numpy 数组称为 x。它的形状如下所示,但它的条目有所不同:(为了回应 Saullo Castro 的评论,我包含了一个略有不同的数组 x。)

array([[ 0.46006547,  0.5580928 ,  0.70164242,  0.84519205,  1.4       ],
[ 0.00912908, 0.00912908, 0.05 , 0.05 , 0.05 ]])

该数组的值沿列单调递增。我还有另外两个数组,分别为 lowest_gridpointshighest_gridpoints。这些数组的条目也有所不同,但形状始终与以下相同:

 array([ 0.633,  0.01 ]), array([ 1.325,  0.99 ])

我要申请的选拔程序如下:

  • 所有包含低于 lowest_gridpoints 中任何值的列都应从 x 中删除,并构成数组 temp1
  • 所有包含高于 highest_gridpoints 中任何值的列都应从 x 中删除,并构成数组 temp2
  • x 中不包含在 temp1temp2 中的所有列构成数组 x_new

我编写的以下代码实现了该任务。

if np.any( x[:,-1] > highest_gridpoints ) or np.any( x[:,0] < lowest_gridpoints ):
for idx, sample, in enumerate(x.T):
if np.any( sample > highest_gridpoints):
max_idx = idx
break
elif np.any( sample < lowest_gridpoints ):
min_idx = idx
temp1, temp2 = np.array([[],[]]), np.array([[],[]])
if 'min_idx' in locals():
temp1 = x[:,0:min_idx+1]
if 'max_idx' in locals():
temp2 = x[:,max_idx:]
if 'min_idx' in locals() or 'max_idx' in locals():
if 'min_idx' not in locals():
min_idx = -1
if 'max_idx' not in locals():
max_idx = x.shape[1]
x_new = x[:,min_idx+1:max_idx]

但是,我怀疑这段代码的效率非常低,因为大量使用了循环。此外,我认为语法过于臃肿。

是否有人有一个想法可以更有效地实现上述任务或看起来简洁的代码?

最佳答案

只有问题的第一部分

from numpy import *

x = array([[ 0.46006547, 0.5580928 , 0.70164242, 0.84519205, 1.4 ],
[ 0.00912908, 0.00912908, 0.05 , 0.05 , 0.05 ]])

low, high = array([ 0.633, 0.01 ]), array([ 1.325, 0.99 ])

# construct an array of two rows of bools expressing your conditions
indices1 = array((x[0,:]<low[0], x[1,:]<low[1]))
print indices1

# do an or of the values along the first axis
indices1 = any(indices1, axis=0)
# now it's a single row array
print indices1

# use the indices1 to extract what you want,
# the double transposition because the elements
# of a 2d array are the rows
tmp1 = x.T[indices1].T
print tmp1

# [[ True True False False False]
# [ True True False False False]]
# [ True True False False False]
# [[ 0.46006547 0.5580928 ]
# [ 0.00912908 0.00912908]]

next 构造类似 indices2tmp2,剩余的索引是前两个索引的的否定。 (即,numpy.logic_not(numpy.logic_or(i1,i2)))。

附录

另一种方法,如果您有数千个条目,可能会更快,意味着 numpy.searchsorted

from numpy import *

x = array([[ 0.46006547, 0.5580928 , 0.70164242, 0.84519205, 1.4 ],
[ 0.00912908, 0.00912908, 0.05 , 0.05 , 0.05 ]])

low, high = array([ 0.633, 0.01 ]), array([ 1.325, 0.99 ])

l0r = searchsorted(x[0,:], low[0], side='right')
l1r = searchsorted(x[1,:], low[1], side='right')

h0l = searchsorted(x[0,:], high[0], side='left')
h1l = searchsorted(x[1,:], high[1], side='left')

lr = max(l0r, l1r)
hl = min(h0l, h1l)

print lr, hl
print x[:,:lr]
print x[:,lr:hl]
print x[:,hl]

# 2 4
# [[ 0.46006547 0.5580928 ]
# [ 0.00912908 0.00912908]]
# [[ 0.70164242 0.84519205]
# [ 0.05 0.05 ]]
# [ 1.4 0.05]

排除重叠可以通过hl = max(lr, hl)获得。注意,在以前的方法中,数组切片被复制到新对象,在这里您可以获取 x 上的 View ,并且如果您想要新对象,则必须明确表示。

编辑 不必要的优化

如果我们在第二个 sortedsearches 中仅使用 x 的上半部分(如果您查看代码,您就会明白我的意思...... )我们得到两个好处,1)搜索速度有非常小的加速(sortedsearch总是足够快),2)自动管理重叠的情况。

作为奖励,在新数组中复制 x 段的代码。 NB x 已更改为强制重叠

from numpy import *

# I changed x to force overlap
x = array([[ 0.46006547, 1.4 , 1.4, 1.4, 1.4 ],
[ 0.00912908, 0.00912908, 0.05, 0.05, 0.05 ]])

low, high = array([ 0.633, 0.01 ]), array([ 1.325, 0.99 ])

l0r = searchsorted(x[0,:], low[0], side='right')
l1r = searchsorted(x[1,:], low[1], side='right')
lr = max(l0r, l1r)

h0l = searchsorted(x[0,lr:], high[0], side='left')
h1l = searchsorted(x[1,lr:], high[1], side='left')

hl = min(h0l, h1l) + lr

t1 = x[:,range(lr)]
xn = x[:,range(lr,hl)]
ncol = shape(x)[1]
t2 = x[:,range(hl,ncol)]

print x
del(x)
print
print t1
print
# note that xn is a void array
print xn
print
print t2

# [[ 0.46006547 1.4 1.4 1.4 1.4 ]
# [ 0.00912908 0.00912908 0.05 0.05 0.05 ]]
#
# [[ 0.46006547 1.4 ]
# [ 0.00912908 0.00912908]]
#
# []
#
# [[ 1.4 1.4 1.4 ]
# [ 0.05 0.05 0.05]]

关于python - 有效地选择 numpy 数组的子部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26463273/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com