2017-02-22 20 views
0

Анализ четвёрки Я делаю выходы 5 полей данных, каждый из которых я собрал в массивы с 1-м номером: freq bin #, амплитуда, длина волны, нормализованная амплитуда,% мощности ,Как структурировать несколько массивов python для сортировки

Как лучше структурировать данные, чтобы сортировать по нисходящей амплитуде?

При тестировании с помощью только одного поля данных, я был в состоянии использовать Dict следующим образом:

fourier_tuples = zip(range(len(fourier)), fourier) 
fourier_map = dict(fourier_tuples) 
import operator 
fourier_sorted = sorted(fourier_map.items(), key=operator.itemgetter(1)) 
fourier_sorted = np.argsort(-fourier)[:3] 

Моя цель в том, чтобы добавить другие массивы в линию 1, но это не работает, так как dicts принимайте только 2 условия. (Вот почему this post не решает мою проблему.)

Отступаем назад, это разумный подход, или есть ли лучшие способы объединения & сортировать отдельные массивы? В конечном счете, я хочу взять значения данных из трех верхних частот и связанных с ними других данных и записать их в выходной файл данных.

Вот отрывок из моих данных:

fourier = np.array([1.77635684e-14, 4.49872050e+01, 1.05094837e+01, 8.24322470e+00, 2.36715913e+01]) 
freqs = np.array([0.  , 0.00246951, 0.00493902, 0.00740854, 0.00987805]) 
wavelengths = np.array([inf, 404.93827165, 202.46913583, 134.97942388, 101.23456791]) 
amps = np.array([4.33257766e-16, 1.09724890e+00, 2.56328871e-01, 2.01054261e-01, 5.77355886e-01]) 
powers% = np.array([4.8508237956526163e-32, 0.31112370227749603, 0.016979224022185751, 0.010445983875848858, 0.086141014686372669]) 

Последние 4 массивов и другие поля, соответствующие «Фурье». (Фактическая длина массива равна 42, но для простоты уменьшена до 5).

+0

Не могли бы вы добавить данные ?! – Cleb

+1

Массивы? Вы имеете в виду * списки *? Почему вы используете 'dict', а затем просто вызываете' items'? Это не имеет никакого смысла ... –

+0

is 'zip (range (len (fourier)), fourier)' short для 'enumerate (fourier)'? –

ответ

1

Вы, кажется, используете numpy, так что здесь есть способ numpy. Вы имеете право функции np.argsort в вашем посте, но ты, кажется, не правильно использовать:

order = np.argsort(amplitudes) 

Это похоже на ваш словарь трюка только он вычисляет обратный шаркая по сравнению с вашей процедурой. Btw. зачем проходить через словарь, а не просто список кортежей?

Содержание order теперь индексы в amplitudes первая ячейка order содержит позицию наименьшего элемента amplitudes, вторая ячейка содержит положение следующего и т.д. Поэтому

top5 = order[:-6:-1] 

прилагающегося ваши данные является 1d Numpy array s вы можете использовать top5 извлечь элементы, соответствующие топ-5 ampltiudes с помощью передовой индексации

freq_bin[top5] 
amplitudes[top5] 
wavelength[top5] 

Если вы хотите, вы можете сгруппировать их вместе в колоннах и применить top5 к полученному п-по-5 массива:

np.c_[freq_bin, amplitudes, wavelength, ...][top5, :] 
+0

Я новичок в numpy и просто подражал подходу, который я видел в другом месте. Я не удивлен, что это не лучший способ. Если кортежи более разумны, тем лучше. Я создал кортежи следующим образом: 'fourier_tuples = zip (диапазон (len (fourier)), частоты, длины волн, дальномеры, усилители, мощности). Затем создайте «top5», как указано выше, и запустите 'fourier_tuples [top5]'. РЕЗУЛЬТАТ: «TypeError: только целые массивы с одним элементом могут быть преобразованы в индекс» – joechoj

+1

@joechoj Я имел в виду кортежи, если вы хотите работать по строкам своей первоначальной попытки. Когда вы вызываете '.items()' пары ключ-значение вашего словаря, преобразуются в кортежи, но таким образом вы можете группировать только 2, со списком кортежей, которые вы можете сгруппировать. - Как я утверждаю в ответе, если вы хотите использовать мой подход, вы должны использовать массивы numpy, потому что они понимают расширенную индексацию, кортежи - нет. Эквивалентом zip в терминах numpy является 'np.c _ [...]' в последней строке –

0

Если я правильно понимаю, у вас есть 5 отдельных списков одинаковой длины и вы пытаясь отсортировать их по одному из них. Для этого вы можете либо использовать numpy, либо сделать это с помощью vanilla python. Вот два примера из верхней части моей головы (сортировка основана на втором списке).

a = [11,13,10,14,15] 
b = [2,4,1,0,3] 
c = [22,20,23,25,24] 

#numpy solution 
import numpy as np 

my_array = np.array([a,b,c]) 
my_sorted_array = my_array[:,my_array[1,:].argsort()] 

#vanilla python solution 
from operator import itemgetter 

my_list = zip(a,b,c) 
my_sorted_list = sorted(my_list,key=itemgetter(1)) 

Вы можете перевернуть массив с my_sorted_array = np.fliplr(my_sorted_array), если вы хотите, или если вы работаете со списками вы можете отменить его в месте с my_sorted_list.reverse()

EDIT:

Чтобы получить первые п значений только, вы должны просто slice массив, аналогичный тому, что предлагает @Paul. Слайс выполняется аналогично классическому разрезанию списков, указав аргументы start:stop:step (вы можете опустить шаг). В вашем случае для 5 верхних столбцов это будет [:,-5:]. Таким образом, в приведенном выше примере вы можете взять верхние 2 колонков из каждой строки, как это:

my_sliced_sorted_array = my_sorted_array[:,-2:] 

результата будет:

array([[15, 13], 
     [ 3, 4], 
     [24, 20]]) 

Надеется, что это помогает.

+0

Мне нравится решение numpy, но не может заставить его работать. Я создал «my_flipped_array», как вы сказали. Может ли массив быть усеченным, чтобы включить только верхние значения x? Хотя, возможно, мне не нужно это делать, так как результаты все доступны с помощью индексации ... – joechoj

+0

А, спасибо. Я пытался «my_flipped_array [:] [: 3]», который каким-то образом возвращал весь набор данных. Любая идея, почему это не работает? В отличие от этого, 'my_flipped_array [0] [: 3]' возвращает первые 3 значения из первого массива. – joechoj

+0

Кто бы ни отклонил этот ответ, не могли бы вы объяснить? Это похоже на прекрасный подход ко мне ... Есть ли какая-то причина, с которой я столкнулся с проблемами? Как-то лучше ответить на @Paul Panzer? – joechoj