#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]))
Спасибо!