Имеются 2 массива данных I(e,t) в виде 2 троек 1-мерных массивов одинаковой длины: t1, e1, I1 и t2, e2, I2. (Точнее, это — группы в открытых HDF-файлах f1['data/t'], f1['data/e'], f1['data/i'] и f2['data/t'], f2['data/e'], f2['data/i']). Данные отсортированны по возрастанию e, затем по возрастанию t. e и t образуют регулярную сетку с шагами ~0.001 и 1. I задана не во всех узлах. Повторяющихся узлов нет.
Требуется проверить, совпадают ли массивы I1 и I2. Оба файла содержат одинаковый набор пар e-t. Но из-за ошибок округления часть изначально совпадавших e немного отличается. Поэтому данные в I2 перетасованы относительно I1 — одинаковые индексы необязательно соответствуют одинаковым значениям e и t.
Имеется питоновская библиотека для чтения этих файлов, h5py. Есть ли какой-то штатный способ быстро отсортировать I2, вначале сравнивая t как целые числа, а затем e — как дробные с заданной погрешностью (скажем, абсолютная погрешность 1e-3)? Реализовать это сам я могу, но вдруг есть готовое?
Можно ли получить искомое, применив numpy.sort к list( zip( t1, e2, I2 ) ) ? Как там задать погрешность? Или есть что-то получше?
Пока сделал так:
#!/usr/bin/python3
from sys import argv
import h5py
import numpy as np
f1, f2 = h5py.File( argv[1],'r' ), h5py.File( argv[2],'r' )
I1, I2 = np.array(f1['data/i']), np.array(f2['data/i'])
t1, t2 = np.array(f1['data/t']), np.array(f2['data/t'])
e1, e2 = np.ma.round(np.array(f1['data/e']), 7), np.ma.round(np.array(f2['data/e']), 7)
j1, j2 = np.lexsort( (e1, t1) ), np.lexsort( (e2, t2) )
a1 = np.stack( ( t1[j1], e1[j1], I1[j1] ), axis=-1 )
a2 = np.stack( ( t2[j2], e2[j2], I2[j2] ), axis=-1 )
print( ( a1 == a2 ).all() )
Или так:
#!/usr/bin/python3
from sys import argv
import h5py
import numpy as np
f1, f2 = h5py.File( argv[1],'r' ), h5py.File( argv[2],'r' )
I1, I2 = np.array(f1['data/i']), np.array(f2['data/i'])
t1, t2 = np.array(f1['data/t']), np.array(f2['data/t'])
e1, e2 = np.array(f1['data/e']), np.array(f2['data/e'])
j1, j2 = np.lexsort( (e1, t1) ), np.lexsort( (e2, t2) )
print( ( t1[j1] == t2[j2] ).all() and
( abs(e1[j1] - e2[j2]) < 0.0000001 ).all() and
( abs(I1[j1] - I2[j2]) < 1 ).all() )