我拥有的一小段数据集如下:
import numpy
fns = numpy.array(["filename_0004_0003_info.hdf5", "filename_0003_0003_info.hdf5", "filename_0001_0001_info.hdf5", "filename_0002_0001_info.hdf5", "filename_0006_0002_info.hdf5", "filename_0005_0002_info.hdf5"])
我称之为run
的第一个整数,而第二个整数I表示为order
。我想对这个数据集进行排序。首先基于order
号码,第二个基于run
号码。每个order
号码都存在两次,而run
号码是唯一的。当我仅使用order
时基于numpy.argsort()
数字进行排序:
order_nrs = numpy.array([int(fn.split("_")[2]) for fn in fns])
fns = numpy.copy(fns)[numpy.argsort(order_nrs)]
我获得了
['filename_0001_0001_info.hdf5' 'filename_0002_0001_info.hdf5' 'filename_0006_0002_info.hdf5' 'filename_0005_0002_info.hdf5' 'filename_0004_0003_info.hdf5' 'filename_0003_0003_info.hdf5']
虽然fns
基于order
排序,但之后也应按run
排序。结果应该是:
filename_0001_0001_info.hdf5
filename_0002_0001_info.hdf5
filename_0005_0002_info.hdf5
filename_0006_0002_info.hdf5
filename_0003_0003_info.hdf5
filename_0004_0003_info.hdf5
我如何实现这一目标?
答案 0 :(得分:0)
fns = ["filename_0004_0003_info.hdf5", "filename_0003_0003_info.hdf5", "filename_0001_0001_info.hdf5", "filename_0002_0001_info.hdf5", "filename_0006_0002_info.hdf5", "filename_0005_0002_info.hdf5"]
def sortfunc(s):
words = s.split('_')
run, order = int(words[1]), int(words[2])
return order, run
fns.sort(key=sortfunc)
答案 1 :(得分:0)
有点冗长,但看到'命令' argsort中的参数。
fns = np.array(["filename_0004_0003_info.hdf5", "filename_0003_0003_info.hdf5", "filename_0001_0001_info.hdf5", "filename_0002_0001_info.hdf5",
"filename_0006_0002_info.hdf5", "filename_0005_0002_info.hdf5"])
o = np.array([fn.split("_") for fn in fns])
a_r = np.core.records.fromarrays(o.transpose(),
names=['a', 'b', 'c', 'd'],
formats=['U9']*4)
idx = np.argsort(a_r, order=['c', 'b'])
out = fns[idx]
out
Out[22]:
array(['filename_0001_0001_info.hdf5', 'filename_0002_0001_info.hdf5',
'filename_0005_0002_info.hdf5', 'filename_0006_0002_info.hdf5',
'filename_0003_0003_info.hdf5', 'filename_0004_0003_info.hdf5'],
dtype='<U28')
从文件名开始,像你一样在_
上拆分,转换为重新排列或结构化数组(给出一个简单的例子),使用argsort但是对你想要使用的两个数字类型进行排序。 。并使用idx
索引对原始内容进行重新排序。
可能还有其他优雅的方式,但我喜欢看到发生了什么,argsort
订单属性让我清楚。糟糕的是,你不能使用索引号而不是命名字段
答案 2 :(得分:0)
一种方法是设计dtype,使得只有两个数字可见,第二个数字首先出现:
>>> fns = numpy.array(["filename_0004_0003_info.hdf5", "filename_0003_0003_info.hdf5", "filename_0001_0001_info.hdf5", "filename_0002_0001_info.hdf5", "filename_0006_0002_info.hdf5", "filename_0005_0002_info.hdf5"])
>>> fns.view(np.dtype({'names':['f1','f2'], 'formats':['<U4','<U4'], 'offsets':[56,36], 'itemsize':112})).sort()
>>> fns
array(['filename_0001_0001_info.hdf5', 'filename_0002_0001_info.hdf5',
'filename_0005_0002_info.hdf5', 'filename_0006_0002_info.hdf5',
'filename_0003_0003_info.hdf5', 'filename_0004_0003_info.hdf5'],
dtype='<U28')
这是直接就地排序,但argsort
当然也有效。
答案 3 :(得分:0)
查看np.lexsort
,它会在一系列键上使用稳定排序来执行您想要的操作。