2014-10-20 43 views
1

我想根据逻辑比较将numpy数组分成三个不同的数组。我想分割的numpy数组叫做x。它的外形看起来如下,但它的条目有所不同:(针对Saullo卡斯特罗的评论我包括一个稍微不同的数组x)高效选择numpy数组的分段

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
  • 包含在temp1temp2中的所有列x构成阵列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] 

但是,我怀疑这个代码是非常低效的,因为大量使用循环。另外,我认为语法臃肿。

有人有一个代码的想法,实现上述任务更有效或看起来简洁吗?

+0

您的示例返回'[]'我...这将是不错的,可用于比较不同的输入... – 2014-10-20 10:27:33

+1

@SaulloCastro:谢谢你的评论。我稍微修改了数组x。你有关于如何修改我的代码的想法吗? – fabian 2014-10-20 14:30:16

+1

你是否期望temp1和temp2是互斥的,或者它可能发生的情况是一个列的值低于'lowest_gridpoints'中的值而另一个值高于'highest_gridpoints'中的值?另外,你的意思是沿着行单调增长吗? – greschd 2014-10-20 16:50:08

回答

1

只有你的问题

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]] 

的第一部分,接下来的构造类似indices2tmp2,剩余的指标是or ING前两个指数的否定。 (即,numpy.logical_not(numpy.logical_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)获得。注意,在previuos方法中,数组切片被复制到新对象,在这里您可以获得x上的视图,如果需要新对象,则必须明确。

编辑一个不必要的优化

如果我们只使用x上部第二夫妇sortedsearch ES(如果你看一下代码,你会明白我的意思?)我们有两个好处,1)搜索速度非常小(总是足够快),并且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]] 
+0

我开始害怕我没有理解OP的要求。 – gboffi 2014-10-21 05:41:51

+0

感谢您的回答;你的Appendum对我来说工作得非常好,除了一个修改:为避免重叠,我不得不使用''如果hl fabian 2014-10-21 12:54:55