Сортировать массив строк numpy с отрицательными числами?

#python #arrays #sorting #numpy

#python #массивы #сортировка #numpy

Вопрос:

У меня возникла проблема с сортировкой массива numpy, который содержит числа в виде строк. Мне нужно сохранить их как строки, потому что после целых чисел есть другие слова.

Он сортирует отрицательные числа в обратном порядке:

 >>> import numpy as np
>>> a = np.array(["3", "-2", "-1", "0", "2"])
>>> a.sort()
>>> a
array(['-1', '-2', '0', '2', '3'], dtype='|S2')
  

Я бы ожидал, что результат будет:

 array(['-2', '-1', '0', '2', '3'], dtype='|S2')
  

Есть предложения?

Комментарии:

1. Итак, вы храните два типа данных в одной строке? Кажется, не особенно подходит для numpy .

2. «Мне нужно сохранить их как строки, потому что после целых чисел есть другие слова». Итак, у вас есть строка like "76 trombones" , и вы хотите обработать ее как число 76 , за которым следует слово "trombones" ? Затем сделайте это . Проанализируйте строки и создайте 2 кортежа (число, остальная часть строки).

3. Нет, это неправильно. Иногда это число и строка, иногда это просто строка. Работает подход «естественной сортировки».

Ответ №1:

Вы могли бы использовать естественную сортировку:

 import numpy as np
import re

def atoi(text):
    try:
        return int(text)
    except ValueError:
        return text

def natural_keys(text):
    '''
    alist.sort(key=natural_keys) sorts in human order
    http://nedbatchelder.com/blog/200712/human_sorting.html
    '''    
    return [ atoi(c) for c in re.split('([-]?d )', text) ]

a = np.array(["3", "-2", "-1", "0", "2", "word"])
print(sorted(a,key=natural_keys))
# ['-2', '-1', '0', '2', '3', 'word']

a = np.array(["3", "-2", "-1", "0", "2", "word", "-1 word", "-2 up"])
print(sorted(a,key=natural_keys))
# ['-2', '-2 up', '-1', '-1 word', '0', '2', '3', 'word']
  

Комментарии:

1. Это приведет к неправильному порядку, если вы попытаетесь выполнить сортировку ["-1 word", "-2 up"] , что, я думаю, подразумевал ОП под «другими словами после целых чисел».

2. Я опубликовал вывод, когда массив содержит ["-1 word", "-2 up"] . Я думаю, что порядок правильный, нет?

3. Вы правы. Я неправильно прочитал ваше регулярное выражение. Для меня это выглядит хорошо, в зависимости от того, как вы хотите обработать случай, когда целое число не отображается в начале строки! (У меня возникает ошибка ValueError.)

Ответ №2:

Предполагая, что после целого числа перед другими словами есть пробел, тогда, если a бы это был обычный python list , вы бы сделали:

 a.sort(key = lambda s: int(s.split()[0]))
  

Не уверен, что эквивалентно в numpy (не вижу, как указать ключ), но одна из возможностей — преобразовать в список и обратно в массив.

Комментарии:

1. Ваша версия работает с. sorted(a, key = lambda s: int(s.split()[0])) Спасибо!