在数组中按行应用argsort,根据阈值跳过某些元素-numpython
我想应用一个排序操作,每行一行,仅将值保持在给定阈值以上 为此,我可以使用屏蔽数组来应用阈值。 但是,在数组中按行应用argsort,根据阈值跳过某些元素-numpython,python,numpy,np.argsort,Python,Numpy,Np.argsort,我想应用一个排序操作,每行一行,仅将值保持在给定阈值以上 为此,我可以使用屏蔽数组来应用阈值。 但是,argsort一直在考虑屏蔽值(低于阈值),并用fill\u值替换它们 但是,如果该值已替换为NaN,则我不希望得到任何结果 a = np.array([[0.522235,0.128270,0.708973], [0.994557,0.844426,0.366608], [0.986669,0.143659,0.395891],
argsort
一直在考虑屏蔽值(低于阈值),并用fill\u值替换它们
但是,如果该值已替换为NaN,则我不希望得到任何结果
a = np.array([[0.522235,0.128270,0.708973],
[0.994557,0.844426,0.366608],
[0.986669,0.143659,0.395891],
[0.291339,0.421843,0.278869],
[0.250303,0.861475,0.904534],
[0.973436,0.360466,0.751913]])
threshold = 0.5
m_a = np.ma.masked_less_equal(a, threshold)
argsorted = m_a.argsort(-1)
这给了我:
array([[0, 2, 1],
[1, 0, 2],
[0, 1, 2],
[0, 1, 2],
[1, 2, 0],
[2, 0, 1]])
但我想得到:
array([[0, NaN, 1],
[1, 0, NaN],
[0, NaN, NaN],
[NaN, NaN, NaN],
[NaN, 0, 1],
[ 1, NaN, 0]])
有没有办法达到这个结果
谢谢你的帮助!
最好,我们可以再添加一个argsort
,以便更轻松地获得所需的输出-
sidx = argsorted.argsort(1)
mask = sidx >= (a.shape[1]-m_a.mask.sum(1,keepdims=True))
out = np.where(mask,np.nan,sidx)
我们也可以从头开始,以避免屏蔽数组
-
def thresholded_argsort(a, threshold):
m = a<threshold
ac = a.copy()
ac[m] = ac.max()+1
sidx = ac.argsort(1).argsort(1)
mask = sidx>=(ac.shape[1]-m.sum(1,keepdims=True))
return np.where(mask,np.nan,sidx)
注意:我们可以使用数组分配
避免额外的argsort,以提高性能。因此,对于沿第二轴的2D
阵列,它将是-
def argsort_unique2D(idx):
m,n = idx.shape
idx_out = np.empty((m,n),dtype=int)
np.put_along_axis(idx_out, idx, np.arange(n), axis=1)
return idx_out
< > >代码> > AgSoReord.AgRoSoT(1)可以替换为<代码> AgRoStTyUnQue2D(AgSRead)< /C>,而<代码> A.ARQORE(1).ARGREST(1)< /> > <代码> AgRoStTyUnQueD2D(AC.ARGREST(1))< /代码>在较早发布的解决方案中。 < P>如果我理解正确,则不想考虑NaN来进行排序。在这种情况下,我不确定你预期结果背后的逻辑。您可以尝试以下代码。我相信这就是你想要的:-
import numpy as np
a = np.array([[0.522235,0.128270,0.708973],
[0.994557,0.844426,0.366608],
[0.986669,0.143659,0.395891],
[0.291339,0.421843,0.278869],
[0.250303,0.861475,0.904534],
[0.973436,0.360466,0.751913]])
threshold = 0.5
m_a = np.ma.masked_less_equal(a, threshold).filled(np.nan)
result = np.where(
np.isnan(m_a),
np.nan, m_a.argsort(-1)
)
result
它应该会给您以下结果:-
array([[ 0., nan, 1.],
[ 1., 0., nan],
[ 0., nan, nan],
[nan, nan, nan],
[nan, 2., 0.],
[ 2., nan, 1.]])
希望这有帮助 a=np.数组([[0.522235,0.128270,0.708973],
[0.994557,0.844426,0.366608],
[0.986669,0.143659,0.395891],
[0.291339,0.421843,0.278869],
[0.250303,0.861475,0.904534],
[0.973436,0.360466,0.751913]])
阈值=.5
def tri(木质素):
s=已排序(直线,键=λx:x<阈值和浮点('inf')或x)
nv_liste=[s.index(v)表示对齐中的v]
对于范围内的i(len(ligne)):
如果ligne[i]<阈值:
nv_liste[i]=np.nan
返回nv_列表
np.沿_轴(tri,1,a)应用_
给你:
数组([[0,nan,1.],
[1,0,nan],
[0,楠,楠],
[楠,楠,楠],
[nan,0,1.],
[1.,nan,0.]]
最后一行似乎不匹配。我不理解预期结果中从第三行到最后一行的逻辑。AFAIU,对于所有高于阈值的元素,索引顺序应为0…n。不考虑NaN进行排序不应更改IMO元素的索引。@TuhinSharma感谢您的帮助。但我也不明白第三排后面的逻辑。我可以理解,应该可以设计一个函数,在过滤NaN之前保留索引。但是这个逻辑也应该适用于前3行。因此,要么在排序后过滤nan,在这种情况下,索引从2开始按降序排列(我们在示例中的第5行和第6行遇到这种情况),要么在排序之前进行过滤,索引从0开始按升序排列,这是示例的第一行。还是我遗漏了什么?是的,你是对的,我马上纠正。嗨@Divakar,谢谢你的帮助。我正在研究这个方向。始终有兴趣学习新技巧并获得更高性能的代码:)。您介意用argsort\u unique
详细说明您的食谱吗?已经谢谢你的帮助了@pierre_j加入了帖子。谢谢@Divakar。我开始玩你之前的帖子,你在其中展示了argsort\u unique
,但确实遇到了索引问题argsort\u unique2D
处理此问题,非常感谢!你好,大卫,谢谢你的帮助。将您的提案与Divakar的提案相比,速度大约慢了80倍。在100k阵列上,这将开始可见;)。尽管如此,还是要谢谢你!
array([[ 0., nan, 1.],
[ 1., 0., nan],
[ 0., nan, nan],
[nan, nan, nan],
[nan, 2., 0.],
[ 2., nan, 1.]])