Python 确定列表中所有非支配项的快速(er)方法

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

我有一个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)
如果可以直接将列表创建为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