2016-10-25 4 views
0

У меня есть массив данных выглядит, например, как:питон - сортировка поплавки внутри элементов массива на основе другого массива

data = [ 
    [1.4, 2.6, 7.3, 4.2], 
    [1.1, 2.0, 6.4, 1.0], 
    [5.1, 6.2, 5.3, 9.9] 
] 

и другой массив с классом этикетками:

class_labels = ['a', 'b', 'a', 'b'] 

Каждого ярлыков классов соответствует определенным поплавкам в каждом элементе массива данных (например, класс 'a' соответствует 1.4 и 7.3 от data[0], иот data[1] и 5.1 и 5.3 от data[0]).

Я понимаю из других сообщений, как я мог бы сортировать один массив на основе другого массива, но можно ли отсортировать массив class_labels в алфавитном порядке, а также отсортировать соответствующие поплавки внутри каждого элемента массива данных?

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

Спасибо за любой совет!

ответ

1

Можно сортировать массивы на основе порядка сортировки другого, но я бы предложил словарь вместо этого, поскольку с ним, вероятно, будет легче работать. Что-то вроде:

data_by_class = {label:[] for label in set(class_labels)} 
for row in data: 
    for idx in range(len(row)): 
     data_by_class[class_labels[idx]].append(row[idx]) 

, который приведет к

{ 'a':[1.4, 7.3, 1.1, 6.4, 5.1, 5.3], 'b': [2.6, 4.2, 2.0, 1.0, 6.2, 9.9] } 
1

Вы, вероятно, хотите организовать данные по-разному, хотя его немного неясно, что именно вы ищете.

Если мы предположим, что вы все равно как данные на основе строк, где каждая строка состоит из (возможно, нескольких) наблюдений различных классов, то вы могли бы реорганизовать данные в список словарей

import itertools 
row_dicts = [{k: [x[1] for x in v] 
       for k, v in itertools.groupby(
        sorted(zip(class_labels, row)), key=lambda x: x[0])} 
      for row in data] 

Теперь ваш данные отображаются в виде:

>>> row_dicts 
[{'a': [1.4, 7.3], 'b': [2.6, 4.2]}, 
{'a': [1.1, 6.4], 'b': [1.0, 2.0]}, 
{'a': [5.1, 5.3], 'b': [6.2, 9.9]}] 

И вы можете обнаружить, например, все наблюдения с этикетками a из ряда 1

>>> row_dicts[1]["a"] 
[1.1, 6.4] 
1

Давайте начнем с вами данных

In [1]: data = [ 
    ...:  [1.4, 2.6, 7.3, 4.2], 
    ...:  [1.1, 2.0, 6.4, 1.0], 
    ...:  [5.1, 6.2, 5.3, 9.9] 
    ...: ] 
In [2]: labels = ['a', 'b', 'a', 'b'] 

Zip это, чтобы объединить два массива в один объект

In [3]: zip(labels, *data) 
Out[3]: 
[('a', 1.4, 1.1, 5.1), 
('b', 2.6, 2.0, 6.2), 
('a', 7.3, 6.4, 5.3), 
('b', 4.2, 1.0, 9.9)] 

Теперь сортировать результат:

In [4]: sorted(zip(labels, *data)) 
Out[4]: 
[('a', 1.4, 1.1, 5.1), 
('a', 7.3, 6.4, 5.3), 
('b', 2.6, 2.0, 6.2), 
('b', 4.2, 1.0, 9.9)] 

Затем распаковать его обратно:

In [6]: zip(*sorted(zip(labels, *data))) 
Out[6]: 
[('a', 'a', 'b', 'b'), 
(1.4, 7.3, 2.6, 4.2), 
(1.1, 6.4, 2.0, 1.0), 
(5.1, 5.3, 6.2, 9.9)] 

И, наконец, получить результат с некрасиво Oneliner

In [7]: [list(x) for x in zip(*sorted(zip(labels, *data)))[1:]] 
Out[7]: [[1.4, 7.3, 2.6, 4.2], [1.1, 6.4, 2.0, 1.0], [5.1, 5.3, 6.2, 9.9]] 

Вы можете разделить Oneliner, если вы хотите, чтобы сделать код более читаемым

Смежные вопросы