在数组中按行应用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.]])