Python 确定列表中所有非支配项的快速(er)方法
我有一个n个数组的列表,每个数组有4个元素,即(n=2): 我试图找到列表中所有“非支配”的元素,也就是说,它们不受列表中任何其他元素的支配。如果数组中的每个项小于或等于另一个数组中的相应项,则该数组将支配另一个数组。所以Python 确定列表中所有非支配项的快速(er)方法,python,numpy,Python,Numpy,我有一个n个数组的列表,每个数组有4个元素,即(n=2): 我试图找到列表中所有“非支配”的元素,也就是说,它们不受列表中任何其他元素的支配。如果数组中的每个项小于或等于另一个数组中的相应项,则该数组将支配另一个数组。所以 dominates([1, 2, 3, 4], [5, 6, 7, 8]) == True 作为1如何: import numpy as np np.all((np.asarry(l[1])-np.asarry(l[0]))>=0) 如果可以直接将列表创建为nump
dominates([1, 2, 3, 4], [5, 6, 7, 8]) == True
作为1如何:
import numpy as np
np.all((np.asarry(l[1])-np.asarry(l[0]))>=0)
如果可以直接将列表创建为numpy数组,则可以采用类似的方法,即type(l)=np.ndarray
。那么语法应该是:
np.all(p[1])-p[0])>=0)
@Nyps答案的另一个版本:
def dominates(a, b):
return (np.asarray(a) <= b).all()
a
这是一个1000 x 10
数组,模拟1000
行10
元素,它:
from scipy.spatial.distance import cdist
X = cdist(a, a, metric=dominates).astype(np.bool)
X
现在是一个1000 X 1000
矩阵,包含所有条目之间的成对比较。这就是,X[i,j]
包含True
如果样本i
支配样本j
或False
否则
现在,您可以从X
中提取奇特的结果,例如支配它们的示例:
>>> a[50] = 0 # set a row to all 0s to fake a dominant row
>>> X = cdist(a, a, metric=dominates).astype(np.bool)
>>> non_dominated = np.where(X.all(axis=1))[0]
>>> non_dominated
array([50])
位置50
处的样本是标尺,如果您的人口众多,您应该密切关注
现在,如果你只想保留被支配的资源,你可以做:
if non_dominated.size > 0:
return [a[i] for i in non_dominated]
else: # no one dominates every other
return a
作为总结:
import numpy as np
from scipy.spatial.distance import cdist
def get_ruler(a):
X = cdist(a, a, metric=dominates).astype(np.bool)
rulers = np.where(X.all(axis=1))[0]
if rulers.size > 0:
return [a[i] for i in rulers]
else: # no one dominates every other
return a
我不清楚你想达到什么目的。请更新您的问题,使其包含带有示例输入和输出的工作代码。我添加了一些额外的细节,希望能让它更清晰一些。更新了答案以反映您想要的筛选(这是我刚才展示的示例)。np。所有
都应该更快。感谢您的回复!使用scipy的第二部分是我正在寻找的领域,但我需要的不是找到支配其他行的行,而是所有不受任何其他行支配的行。我认为这应该是相当直接的提取从你有-再次感谢@用户8415803操作正确!例如,我确实将名称更改为get\u ruler
。在您的情况下,如果我理解正确,您希望检查列j
,而不是行I
(更改为axis=0
)。虽然,它不是等价的吗?我的意思是,如果一行没有被任何其他行支配,这不意味着它确实支配了每一行吗?(只是好奇,我的逻辑可能在玩弄我)。
import numpy as np
a = np.random.randint(0, 10, size=(1000, 10))
from scipy.spatial.distance import cdist
X = cdist(a, a, metric=dominates).astype(np.bool)
>>> a[50] = 0 # set a row to all 0s to fake a dominant row
>>> X = cdist(a, a, metric=dominates).astype(np.bool)
>>> non_dominated = np.where(X.all(axis=1))[0]
>>> non_dominated
array([50])
if non_dominated.size > 0:
return [a[i] for i in non_dominated]
else: # no one dominates every other
return a
import numpy as np
from scipy.spatial.distance import cdist
def get_ruler(a):
X = cdist(a, a, metric=dominates).astype(np.bool)
rulers = np.where(X.all(axis=1))[0]
if rulers.size > 0:
return [a[i] for i in rulers]
else: # no one dominates every other
return a