Python:使用NaN对数组进行排序

时间:2014-01-17 15:27:02

标签: python arrays numpy nan

注意:我正在使用Python和numpy数组。

我有很多阵列都有两列和多行。第二列中有一些NaN值;第一列只有数字。

我想根据第二列按递增顺序对每个数组进行排序,从而保留NaN值。这是一个很大的数据集,所以我宁愿不必将NaN值转换为零或其他东西。

我希望它像这样排序:

105.  4.
22.   10.
104.  26.
...
...
...
53.   520.
745.  902.
184.  nan
19.   nan

首先,我尝试使用fix_invalid将NaN转换为1x10^20

#data.txt has one of the arrays with 2 columns and a bunch of rows.
Data_0_30 = array(genfromtxt(fname='data.txt'))

g = open("iblah.txt", "a") #saves to file

def Sorted_i_M_W(mass):
    masked = ma.fix_invalid(mass)
    print  >> g, array(sorted(masked, key=itemgetter(1)))

Sorted_i_M_W(Data_0_30)

g.close()

或者我用这样的东西替换了这个函数:

def Sorted_i_M_W(mass):
    sortedmass = sorted( mass, key=itemgetter(1))
    print  >> g, array(sortedmass)

每次尝试我都会得到类似的东西:

...
[  4.46800000e+03   1.61472200e+11]
[  3.72700000e+03   1.74166300e+11]
[  4.91800000e+03   1.75502300e+11]
[  6.43500000e+03              nan]
[  3.95520000e+04   8.38907500e+09]
[  3.63750000e+04   1.27625700e+10]
[  2.08810000e+04   1.28578500e+10]
...

在NaN值的位置,排序再次重新开始。

(对于fix_invalid,上面摘录中的NaN显示1.00000000e+20值。但我希望排序完全忽略NaN值。

按照我想要的方式对这个数组进行排序的最简单方法是什么?

5 个答案:

答案 0 :(得分:5)

不确定是否可以使用numpy.sort完成,但您可以确定使用numpy.argsort

>>> arr
array([[ 105.,    4.],
       [  53.,  520.],
       [ 745.,  902.],
       [  19.,   nan],
       [ 184.,   nan],
       [  22.,   10.],
       [ 104.,   26.]])
>>> arr[np.argsort(arr[:,1])]
array([[ 105.,    4.],
       [  22.,   10.],
       [ 104.,   26.],
       [  53.,  520.],
       [ 745.,  902.],
       [  19.,   nan],
       [ 184.,   nan]])

答案 1 :(得分:4)

您可以创建一个蒙版数组:

a = np.loadtxt('test.txt')

mask = np.isnan(a)
ma = np.ma.masked_array(a, mask=mask)

然后使用蒙面数组对a进行排序:

a[np.argsort(ma[:, 1])]

答案 2 :(得分:1)

您可以使用比较功能

def cmpnan(x, y):
    if isnan(x[1]):
        return 1 # x is "larger"
    elif isnan(y[1]):
        return -1 # x is "smaller"
    else:
        cmp(x[1], y[1]) # compare numbers

sorted(data, cmp=cmpnan)

请参阅http://docs.python.org/2.7/library/functions.html#sorted

答案 3 :(得分:1)

如果您使用的是较旧版本的numpy并且不想升级(或者如果您想要支持旧版本numpy的代码),您可以这样做:

import numpy as np

def nan_argsort(a):
    temp = a.copy()
    temp[np.isnan(a)] = np.inf
    return temp.argsort()

sorted = a[nan_argsort(a[:, 1])]

在numpy的新版本中,我认为至少1.6,numpy的sort / argsort已经有了这种行为。如果由于某种原因需要使用python的排序,可以按照其他答案中的描述制作自己的比较函数。

答案 4 :(得分:0)

如果你真的不想使用numpy数组,你可以对第二列进行排序,然后获取索引来调用你的数组。

它可以像这样在一行中完成:

yourarray[sorted(range(len(yourarray[:,1])), key=lambda k: yourarray[:,1][k])]