Сортировка строк с разделителями в пандах - PullRequest
0 голосов
/ 06 января 2019

У меня есть серия панд со строками в них, как, скажем,

['160.20.2257.92', '829.328.17.39']

Я хочу отсортировать их. Если я использую Seres.sort_values ​​(), как показано в следующем коде:

a = pd.Series(['6.0.0.0', '10.0.4.0'])
a.sort_values()

Я получаю вывод как:

1    10.0.4.0
0     6.0.0.0

, что вполне ожидаемо, поскольку функция сортировки сравнивает 6 с 1, а не 6 с 10, и, поскольку 1 меньше, она отображается первой в отсортированном порядке. Я хочу, чтобы он сортировался по первой части перед разделителем ('.'), Затем по 2-й части и т. Д. (Т. Е. Сравните 10 & 6, затем 0 & 0, затем 4 & 0, наконец, 0 & 0)

Каков наилучший способ в Пандах с точки зрения скорости достижения этого, поскольку я имею дело с большим набором данных?

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Это расширение ответа @Ananay Mital - если вы хотите сохранить индекс.

def sort_data(series): 
    sorted_data = sorted(
                      zip(series.index, map(lambda x: tuple(map(int, x.split('.'))), series)), 
                      key=lambda x: x[1])  
    return pd.Series(
               map(lambda x: '.'.join(map(str, x[1])), sorted_data),
               index=[i[0] for i in sorted_data])

sorted_data = sort_data(series)

Пример:

series
Out:
0       2.49.30.91
1      2.16.99.113
2     62.38.107.41
3     127.21.16.56
4     14.97.112.42
5      49.25.90.11
6      92.87.23.61
7    87.121.78.112
8      17.73.95.37
9     28.117.48.89
dtype: object

Сортированная серия:

sort_data(series)
Out:
1      2.16.99.113
0       2.49.30.91
4     14.97.112.42
8      17.73.95.37
9     28.117.48.89
5      49.25.90.11
2     62.38.107.41
7    87.121.78.112
6      92.87.23.61
3     127.21.16.56
dtype: object

Нет простого способа сделать то, что вы ищете, с помощью стандартных pandas методов; Кроме того, некоторые мои попытки сделать это с пандами были не такими быстрыми, как решение @Ananay Mital.

Этот подход достаточно быстрый (приблизительное время для сортировки 100.000 ip ~ 4 мс, 1.000.000 ip ~ 84 мс).

Если вы хотите, чтобы он работал быстрее, потому что набор данных огромен и O(n)/O(n*log(n)) разница имеет значение, вы можете реализовать сортировку по счету или сортировку по основанию (только если данные состоят из ip или около того - домен должен быть ограничен). Даже реализованный в python, такой алгоритм будет быстрее встроенного sorted из-за сложности O(n).

0 голосов
/ 06 января 2019

Я считаю, что это то, что вы ищете

a = ['160.20.2257.92', '829.328.17.39']
b = sorted(map(lambda x: tuple(map(int, x.split('.'))), a))
final = map(lambda x: '.'.join(map(str, x)), b)
final

['160.20.2257.92', '829.328.17.39']

Я надеюсь, что это охватывает все угловые случаи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...