如何删除或屏蔽numpy数组相对于另一个条目的条目

时间:2015-11-25 05:49:59

标签: python arrays numpy

我有一个看起来像这样的Numpy数组:

X = np.array([(1,2,'Bye'), (1,2,'Zero'), (5,7,'One'), (1,2,'Two'), (5,7,'Bye'),
(500,600,'Three'), (12,40,'Four'), (12,40,'Five'), (5,7,'Bye')],
dtype=[('foo','i4'),('bar','i4'),('baz','S10')])

我尝试创建一个新数组,该数组省略了包含'Bye'的任何条目,以及它之前和之后的条目。

根据我的理解,实现此目的的最有效方法是使用屏蔽数组,但是我只能成功屏蔽'Bye'条目,而不是它们周围的条目:

ma.masked_where(X['baz']==b'Bye', X)

如何将其展开以包含'Bye'之前和之后的条目?我遇到的一个大问题是,有时这些值会重叠,或者不存在(例如,在第一个'Bye'的情况下。

我还尝试了一堆嵌套forif循环np.delete(),但我不想走那条路。

2 个答案:

答案 0 :(得分:2)

数据

.second{ 
   display:inline-block;
   height: 100%;
   width: 100%;
   background-color:red;
   opacity: 0;
   transition: opacity  0.5s ease;    
 }

解决方案

In [55]:
X = np.array([(1,2,'Bye'), (1,2,'Zero'), (5,7,'One'), (1,2,'Two'), (5,7,'Bye'),
(500,600,'Three'), (12,40,'Four'), (12,40,'Five'), (5,7,'Bye')])
X
Out[55]:
array([['1', '2', 'Bye'],
       ['1', '2', 'Zero'],
       ['5', '7', 'One'],
       ['1', '2', 'Two'],
       ['5', '7', 'Bye'],
       ['500', '600', 'Three'],
       ['12', '40', 'Four'],
       ['12', '40', 'Five'],
       ['5', '7', 'Bye']], 
      dtype='|S11')

面膜

# The indeices with `Bye` value   
In [82]:
init_mask_indices = np.where(X[: , 2] == b'Bye')
init_mask_indices
Out[82]:
(array([0, 4, 8], dtype=int64),)

# The indices after rows with `Bye` value
In [81]:
plus_one = init_mask_indices + np.array([1])
plus_one
Out[81]:
array([[1, 5, 9]], dtype=int64)

# The indices before rows with `Bye` value
In [80]:
minus_one = init_mask_indices - np.array([1])
minus_one
Out[80]:
array([[-1,  3,  7]], dtype=int64)

# All indices
In [90]:
arr_all =np.concatenate((init_mask_indices , plus_one , minus_one) , axis = 1)
arr_all
Out[90]:
array([[0,  4,  8,  1,  5,  9, -1,  3,  7]], dtype=int64)

# Final indices
In [96]:
arr_final = np.unique(arr_all[ np.logical_and( arr_all >= 0 , arr_all < len(X)) ]) 
arr_final
Out[96]:
array([0,1, 3, 4, 5, 7, 8], dtype=int64)

答案 1 :(得分:1)

我的意见是,首先将您的数据作为python本地列表处理,然后转换为np.array

X = [(1,2,'Bye'), (1,2,'Zero'), (5,7,'One'), (1,2,'Two'), (5,7,'Bye'),
(500,600,'Three'), (12,40,'Four'), (12,40,'Five'), (5,7,'Bye')]

def my_filter(L, k, word):
    if L[k][2] == word:
        return False
    if k > 0 and L[k-1][2] == word:
        return False
    if k < len(L) - 1 and L[k+1][2] == word:
        return False
    return True

filter_indices, filter_X = zip(*[(i,x) for i,x in enumerate(X) if my_filter(X, i, 'Bye')])
np_filter_X = np.array([x[:2] for x in filter_X])

filter_indices的结果(原始未过滤数据中的过滤索引):

(2, 6) 

filter_X的结果:

[(5, 7, 'One'), (12, 40, 'Four')]

np_filter_X的结果:

array([[ 5,  7],
       [12, 40]])

现在你的np.array实际上是数字,而不是字符串'1','2'等......

编辑:关于数据类型和性能,请参阅以下简单示例:

%timeit np.linalg.matrix_power(1+np.random.rand(100,100), 100)
1000 loops, best of 3: 387 µs per loop

现在完全相同的计算,但使用一般对象作为数据类型:

%timeit np.linalg.matrix_power(1+np.random.rand(100,100).astype("object"), 100)
10 loops, best of 3: 156 ms per loop

慢400倍!