如何基于列表对二维numpy对象数组进行排序

5jvtdoz2  于 2023-03-08  发布在  其他
关注(0)|答案(3)|浏览(110)

我有一个二维numpy对象数组:

aa = np.array([["aaa","05","1","a"],
               ["ccc","30","2","v"],
               ["ddd","50","2","v"],
               ["bbb","10","1","v"]])

和以下列表:

sample_ids = ["aaa", "bbb", "ccc", "ddd"]

我想根据列表对numpy数组进行排序,这样我就得到了以下内容:

[["aaa","05","1","a"],
 ["bbb","10","1","v"],
 ["ccc","30","2","v"],
 ["ddd","50","2","v"]]
    • 编辑**:

如果数组中没有键(在sample_ids中),那么结果数组将不包含这些缺失的键(即不添加空行)。

sample_ids = ["aaa", "bbb", "ccc", "ddd", "eee"]

最后的数组仍然是相同的。
同样,如果数组包含的行(即行键)在键中丢失,那么该行也将被排除在结果数组之外。

    • 编辑2:**从Nick的回答开始,我想出了这个来处理缺少的键。
sample_ids2 = ["aaa", "bbb", "eee", "ccc", "ddd"]

idxs = []
for i,v in enumerate(sample_ids2):
    if str(list(aa.T[0])).find(v) != -1:
        k = list(aa.T[0]).index(v)
        idxs.append(k)
    else:
        print(v + " was not found!!!")

print(aa[idxs])

输出:

[['aaa' '05' '1' 'a']
 ['bbb' '10' '1' 'v']
 ['ccc' '30' '2' 'v']
 ['ddd' '50' '2' 'v']]
sg2wtvxw

sg2wtvxw1#

下面是一些可能的解决方案。使用numpy:

subs = list(aa.T[0])
idxs = [subs.index(i) for i in sample_ids if i in subs]
res = aa[idxs]
# array([['aaa', '05', '1', 'a'],
#        ['bbb', '10', '1', 'v'],
#        ['ccc', '30', '2', 'v'],
#        ['ddd', '50', '2', 'v']], dtype='<U3')

使用Pandas:

res = np.array(pd.DataFrame(aa).set_index(0).reindex(sample_ids).dropna().reset_index())
# array([['aaa', '05', '1', 'a'],
#        ['bbb', '10', '1', 'v'],
#        ['ccc', '30', '2', 'v'],
#        ['ddd', '50', '2', 'v']], dtype=object)

对于这两种情况,如果sample_ids = ["aaa", "bbb", "ccc", "ddd", "eee"],则输出将相同。
如果sample_ids = ["ddd", "aaa", "bbb"],则输出为:

array([['ddd', '50', '2', 'v'],
       ['aaa', '05', '1', 'a'],
       ['bbb', '10', '1', 'v']])
9fkzdhlc

9fkzdhlc2#

灵感来自于@Nick的第一种方法:

# first build a dictionary of value: position
key = {k: i for i, k in enumerate(sample_ids)}
# {'aaa': 0, 'bbb': 1, 'ccc': 2, 'ddd': 3}

# then sort based on this key
out = aa[np.argsort(np.vectorize(key.get)(aa[:, 0]))]

如果您希望能够处理缺失值(首先使用-1作为默认键对其进行排序,如果您希望最后使用np.inf):

out = aa[np.argsort(np.vectorize(lambda x: key.get(x, -1))(aa[:, 0]))]

输出:

array([['aaa', '05', '1', 'a'],
       ['bbb', '10', '1', 'v'],
       ['ccc', '30', '2', 'v'],
       ['ddd', '50', '2', 'v']], dtype='<U3')
7kqas0il

7kqas0il3#

使用numpy.broadcasting的可能解决方案:

aa[np.argmax(aa[:,0] == np.array(sample_ids)[:, None], axis=1), :]

使用list comprehension的另一个可能的解决方案是:

np.vstack([aa[aa[:,0] == x, :] for x in sample_ids])

输出:

array([['aaa', '05', '1', 'a'],
       ['bbb', '10', '1', 'v'],
       ['ccc', '30', '2', 'v'],
       ['ddd', '50', '2', 'v']], dtype='<U3')

相关问题