[英]Test if a numpy array is a member of a list of numpy arrays, and remove it from the list
[英]How do you 'remove' a numpy array from a list of numpy arrays?
如果我有一個 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() 工作,這是不可能的嗎?
這里的問題是,當兩個 numpy 數組與 == 進行比較時,如在 remove() 和 index() 方法中,返回一個布爾值的 numpy 數組(逐元素比較),這被解釋為不明確。 比較兩個 numpy 數組是否相等的一個好方法是使用 numpy 的 array_equal() 函數。
由於列表的 remove() 方法沒有關鍵參數(就像 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 化。
干得好:
list.pop(1)
更新:
list.pop(list.index(element))
我不認為你可以繞過遍歷列表來找到元素的位置。 別擔心。 默認情況下,Python 會使用一種好的搜索算法來為您找到最少的成本。
以下解決方案使用數組列表中的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)
您可以運行以下單行代碼以獲得結果...
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.