当矩阵至少包含一个 nan 时,从矩阵列表中删除任何矩阵的最有效方法是什么?
What is the most efficient way to remove any matrix from a list of matrices when the matrix contains at least one nan?
我有一个矩阵列表,M_list
,我想有效地从列表中删除任何包含 nan
的矩阵
我的方法是查看每个矩阵,对其条目求和,如果总和为 nan
:
,则从列表中删除该矩阵
import numpy as np
# generate list of seven, 5-by-5 matrices each of which
contains two nans:
M_list=[]
for t in range(7):
M=np.random.rand(5,5)
M.ravel()[np.random.choice(M.size, 2, replace=False)] =
np.nan
M_list.append(M)
# Now my attempt
for t in range(len(M_list)):
array_sum = np.sum(M_list[t])
if np.isnan(array_sum):
M_list.remove(M_list[t])
我收到的错误消息指出,具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()。删除循环中的最后一行可以消除错误,但我不明白为什么,因为我只是在尝试执行基本的列表操作。
还有没有更简单的方法来实现我的目标而不使用循环?
您可以使用 isnan
和 any
:
>>> filtered = [arr for arr in M_list if not np.isnan(arr).any()]
虽然列表理解是最好的方法,但您应该尝试理解您的尝试有什么问题。
制作M_list
:
In [733]: len(M_list)
Out[733]: 7
我们可以删除第一个列表元素:
In [734]: M_list.remove(M_list[0])
In [735]: len(M_list)
Out[735]: 6
但是如果我们尝试从剩余列表中删除第二个:
In [736]: M_list.remove(M_list[1])
Traceback (most recent call last):
File "<ipython-input-736-49c29fd4cfcc>", line 1, in <module>
M_list.remove(M_list[1])
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
这种歧义错误经常出现在 SO 上。这是尝试在只接受标量布尔值的 Python 上下文中使用布尔数组的结果,一个简单的 True/False.
remove
必须找到“匹配”value
的列表元素。显然它遍历列表直到找到匹配项。在其他 SO 中已经指出,它首先测试 ID 是否相同。如果失败,它会测试某种值是否相等 (==
)。
这就是删除 M_list[0]
有效的原因,id 匹配。但是要删除 M_list[1]
它必须首先针对列表的第一个元素进行测试,从而导致歧义错误。如果我们尝试删除 copy()
,我们会得到同样的歧义错误,因为 ID 测试不再有效。
In [742]: M_list.remove(M_list[0].copy())
Traceback (most recent call last):
File "<ipython-input-742-6d529bc24c83>", line 1, in <module>
M_list.remove(M_list[0].copy())
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
但是您的迭代删除还有另一个问题:
for t in range(len(M_list)):
array_sum = np.sum(M_list[t])
if np.isnan(array_sum):
M_list.remove(M_list[t])
M_list.remove()
从列表中删除一个项目;该列表更短,因此 M_list[t]
不再指向原始列表的 t
元素。像这样的迭代删除只有在从末尾开始迭代时才有效。通常,列表上的 for
循环仅在列表未在循环中更改(添加或删除)时才有效。否则你应该制作一个新的列表,保持原来的不变。
我有一个矩阵列表,M_list
,我想有效地从列表中删除任何包含 nan
我的方法是查看每个矩阵,对其条目求和,如果总和为 nan
:
import numpy as np
# generate list of seven, 5-by-5 matrices each of which
contains two nans:
M_list=[]
for t in range(7):
M=np.random.rand(5,5)
M.ravel()[np.random.choice(M.size, 2, replace=False)] =
np.nan
M_list.append(M)
# Now my attempt
for t in range(len(M_list)):
array_sum = np.sum(M_list[t])
if np.isnan(array_sum):
M_list.remove(M_list[t])
我收到的错误消息指出,具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()。删除循环中的最后一行可以消除错误,但我不明白为什么,因为我只是在尝试执行基本的列表操作。
还有没有更简单的方法来实现我的目标而不使用循环?
您可以使用 isnan
和 any
:
>>> filtered = [arr for arr in M_list if not np.isnan(arr).any()]
虽然列表理解是最好的方法,但您应该尝试理解您的尝试有什么问题。
制作M_list
:
In [733]: len(M_list)
Out[733]: 7
我们可以删除第一个列表元素:
In [734]: M_list.remove(M_list[0])
In [735]: len(M_list)
Out[735]: 6
但是如果我们尝试从剩余列表中删除第二个:
In [736]: M_list.remove(M_list[1])
Traceback (most recent call last):
File "<ipython-input-736-49c29fd4cfcc>", line 1, in <module>
M_list.remove(M_list[1])
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
这种歧义错误经常出现在 SO 上。这是尝试在只接受标量布尔值的 Python 上下文中使用布尔数组的结果,一个简单的 True/False.
remove
必须找到“匹配”value
的列表元素。显然它遍历列表直到找到匹配项。在其他 SO 中已经指出,它首先测试 ID 是否相同。如果失败,它会测试某种值是否相等 (==
)。
这就是删除 M_list[0]
有效的原因,id 匹配。但是要删除 M_list[1]
它必须首先针对列表的第一个元素进行测试,从而导致歧义错误。如果我们尝试删除 copy()
,我们会得到同样的歧义错误,因为 ID 测试不再有效。
In [742]: M_list.remove(M_list[0].copy())
Traceback (most recent call last):
File "<ipython-input-742-6d529bc24c83>", line 1, in <module>
M_list.remove(M_list[0].copy())
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
但是您的迭代删除还有另一个问题:
for t in range(len(M_list)):
array_sum = np.sum(M_list[t])
if np.isnan(array_sum):
M_list.remove(M_list[t])
M_list.remove()
从列表中删除一个项目;该列表更短,因此 M_list[t]
不再指向原始列表的 t
元素。像这样的迭代删除只有在从末尾开始迭代时才有效。通常,列表上的 for
循环仅在列表未在循环中更改(添加或删除)时才有效。否则你应该制作一个新的列表,保持原来的不变。