给定一个numpy数组
a = np.array([[0, -1, 0], [1, 0, 0], [1, 0, -1]])
如何最快地删除所有值为-1
的元素,以获得以下形式的数组
np.array([[0, 0], [1, 0, 0], [1, 0]])
你可能考虑另一种方法:
def iterative_numpy(a):
mask = a != 1
out = np.array([ a[i,mask[i]] for i xrange(a.shape[0]) ])
return out
loop_compr_based
计算掩码行中的总和以及该结果的累积总和。此方法避免了这样的求和,但仍需迭代a
的行。它还返回一个数组的数组。这种方法的烦恼在于必须使用语法out[1][2]
而不是out[1,2]
来索引out
。将其与随机整数矩阵的时间进行比较:In [4]: a = np.random.random_integers(-1,1, size = (3,30))
In [5]: %timeit iterative_numpy(a)
100000 loops, best of 3: 11.1 us per loop
In [6]: %timeit loop_compr_based(a)
10000 loops, best of 3: 20.2 us per loop
In [7]: a = np.random.random_integers(-1,1, size = (30,3))
In [8]: %timeit iterative_numpy(a)
10000 loops, best of 3: 59.5 us per loop
In [9]: %timeit loop_compr_based(a)
10000 loops, best of 3: 30.8 us per loop
In [10]: a = np.random.random_integers(-1,1, size = (30,30))
In [11]: %timeit iterative_numpy(a)
10000 loops, best of 3: 64.6 us per loop
In [12]: %timeit loop_compr_based(a)
10000 loops, best of 3: 36 us per loop
iterative_numpy
胜出。当行数大于列数时,loop_compr_based
胜出,但先对 a
进行转置将提高两种方法的性能。当维度相同时,loop_compr_based
是最佳选择。
除了实现之外,需要注意的是任何具有非均匀形状的 numpy 数组都不是实际数组,因为值不占据连续的内存空间,而且通常的数组操作将无法正常工作。
例如:
>>> a = np.array([[1,2,3],[1,2],[1]])
>>> a*2
array([[1, 2, 3, 1, 2, 3], [1, 2, 1, 2], [1, 1]], dtype=object)
dtype = object
。方法一:使用NumPy数组分割 -
def split_based(a, val):
mask = a!=val
p = np.split(a[mask],mask.sum(1)[:-1].cumsum())
out = np.array(list(map(list,p)))
return out
方法二:使用循环推导,但在循环内进行最少的操作。
def loop_compr_based(a, val):
mask = a!=val
stop = mask.sum(1).cumsum()
start = np.append(0,stop[:-1])
am = a[mask].tolist()
out = np.array([am[start[i]:stop[i]] for i in range(len(start))])
return out
样例运行 -
In [391]: a
Out[391]:
array([[ 0, -1, 0],
[ 1, 0, 0],
[ 1, 0, -1],
[-1, -1, 8],
[ 3, 7, 2]])
In [392]: split_based(a, val=-1)
Out[392]: array([[0, 0], [1, 0, 0], [1, 0], [8], [3, 7, 2]], dtype=object)
In [393]: loop_compr_based(a, val=-1)
Out[393]: array([[0, 0], [1, 0, 0], [1, 0], [8], [3, 7, 2]], dtype=object)
运行时测试 -
In [387]: a = np.random.randint(-2,10,(1000,1000))
In [388]: %timeit split_based(a, val=-1)
10 loops, best of 3: 161 ms per loop
In [389]: %timeit loop_compr_based(a, val=-1)
10 loops, best of 3: 29 ms per loop
out = np.array(list(map(list,p)))
。 - Kamil Sindia = np.random.randint(-2,10,(1000,1000))
,方法 #2 比方法 #1 快了 5 倍。 - Divakarindexes = np.where(a == -1)
来获取元素的索引
从numpy数组中查找等于零的元素的索引
然后使用np.delete(your_array, indexes)
按索引删除特定元素
如何在numpy数组中删除特定元素
这个怎么样?
print([[y for y in x if y > -1] for x in a])
[[0, 0], [1, 0, 0], [1, 0]]
对于你可能想要使用的数组的几乎所有操作,你都可以使用掩码数组。
a = np.array([[0, -1, 0], [1, 0, 0], [1, 0, -1]])
b=np.ma.masked_equal(a,-1)
b
Out[5]:
masked_array(data =
[[0 -- 0]
[1 0 0]
[1 0 --]],
mask =
[[False True False]
[False False False]
[False False True]],
fill_value = -1)
如果您真的需要不规则数组,可以按行进行.compressed()
处理
c=np.array([b[i].compressed() for i in range(b.shape[0])])
c
Out[10]: array([array([0, 0]), array([1, 0, 0]), array([1, 0])], dtype=object)