如果我有一个numpy数组列表,那么使用remove方法会返回一个值错误。
例如:
import numpy as np
l = [np.array([1,1,1]),np.array([2,2,2]),np.array([3,3,3])]
l.remove(np.array([2,2,2]))
会给我
ValueError:具有多个元素的数组的真值是不明确的。使用a.any()或a.all()
我似乎无法使all()工作,这是不可能的吗?
答案 0 :(得分:11)
这里的问题是当两个numpy数组与==进行比较时,就像在remove()和index()方法中一样,返回一个布尔值的numpy数组(元素比较的元素),这被解释为暧昧。比较两个numpy数组是否相等的好方法是使用numpy的array_equal()函数。
由于list的remove()方法没有key参数(比如sort()),我认为你需要自己创建函数来执行此操作。这是我做的一个:
def removearray(L,arr):
ind = 0
size = len(L)
while ind != size and not np.array_equal(L[ind],arr):
ind += 1
if ind != size:
L.pop(ind)
else:
raise ValueError('array not found in list.')
如果你需要它更快,那么你可以Cython-ize它。
答案 1 :(得分:4)
你走了:
list.pop(1)
更新
list.pop(list.index(element))
我认为你不能遍历列表以找到元素的位置。别担心。默认情况下,Python会使用一个好的搜索算法来为您找到它。
答案 2 :(得分:1)
以下解决方案使用了list.index(element)
方法中的
数组列表。
搜索numpy.ndarray
必须能够哈希numpy.ndarray实例。因此,我们需要实施
哈希算法。这很简单,尽管给出的代码看起来有些长,但是大多数行用于检查边缘情况或添加注释。
您可以将代码复制粘贴到文件中,然后从命令行运行它 或SDK为PyCharm。
您需要了解
注意:
import numpy as np
def remove(array, arrays):
"""
Remove the `array` from the `list` of `arrays`
Operates inplace on the `list` of `arrays` given
:param array: `np.ndarray`
:param arrays: `list:np.ndarray`
:return: None
"""
assert isinstance(arrays, list), f'Expected a list, got {type(arrays)} instead'
assert isinstance(array, np.ndarray), f'Expected a numpy.ndarray, got {type(array)} instead'
for a in arrays:
assert isinstance(a, np.ndarray), f'Expected a numpy.ndarray instances in arrays, found {type(a)} instead'
# Numpy ndarrays are not hashable by default, so we create
# our own hashing algorithm. The following will do the job ...
def _hash(a):
return hash(a.tobytes())
try:
# We create a list of hashes and search for the index
# of the hash of the array we want to remove.
index = [_hash(a) for a in arrays].index(_hash(array))
except ValueError as e:
# It might be, that the array is not in the list at all.
print(f'Array not in list. Leaving input unchanged.')
else:
# Only in the case of no exception we pop the array
# with the same index/position from the original
# arrays list
arrays.pop(index)
if __name__ == '__main__':
# Let's start with the following arrays as given in the question
arrays = [np.array([1, 1, 1]), np.array([2, 2, 2]), np.array([3, 3, 3])]
print(arrays)
# And remove this array instance from it.
# Note, this is a new instance, so the object id is
# different. Structure and values coincide.
remove(np.array([2, 2, 2]), arrays)
# Let's check the result
print(arrays)
# Let's check, whether our edge case handling works.
remove(np.array([1, 2, 3]), arrays)
答案 3 :(得分:1)
您可以运行以下一种代码来获取结果...
import numpy as np
# Your inputs ...
l = [np.array([1, 1, 1]), np.array([2, 2, 2]), np.array([3, 3, 3])]
array_to_remove = np.array([2, 2, 2])
# My result ...
result = [a for a, skip in zip(l, [np.allclose(a, array_to_remove) for a in l]) if not skip]
print(result)
...或复制以下内容,并将其粘贴到脚本中并进行一些试验。
您需要
注意,...
import numpy as np
def remove(array, arrays):
"""
Remove the `array` from the `list` of `arrays`
Returns list with remaining arrays by keeping the order.
:param array: `np.ndarray`
:param arrays: `list:np.ndarray`
:return: `list:np.ndarray`
"""
assert isinstance(arrays, list), f'Expected a list, got {type(arrays)} instead'
assert isinstance(array, np.ndarray), f'Expected a numpy.ndarray, got {type(array)} instead'
for a in arrays:
assert isinstance(a, np.ndarray), f'Expected a numpy.ndarray instances in arrays, found {type(a)} instead'
# We use np.allclose for comparing arrays, this will work even if there are
# floating point representation differences.
# The idea is to create a boolean mask of the same lenght as the input arrays.
# Then we loop over the arrays-elements and the mask-elements and skip the
# flagged elements
mask = [np.allclose(a, array) for a in arrays]
return [a for a, skip in zip(arrays, mask) if not skip]
if __name__ == '__main__':
# Let's start with the following arrays as given in the question
arrays = [np.array([1, 1, 1]), np.array([2, 2, 2]), np.array([3, 3, 3])]
print(arrays)
# And remove this array instance from it.
# Note, this is a new instance, so the object id is
# different. Structure and values coincide.
_arrays = remove(np.array([2, 2, 2]), arrays)
# Let's check the result
print(_arrays)
# Let's check, whether our edge case handling works.
print(arrays)
_arrays = remove(np.array([1, 2, 3]), arrays)
print(_arrays)