pandas: перевести часть строки из десятичного в шестнадцатеричное счисление

Имеется таблица, в которой есть столбец со строковыми данными. В каждой строке необходимо перевести часть строки из десятичного значение в шестнадцатеричное.

  1. Имеются строки в столбцах.

SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.50.108 = INTEGER: 0

SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.50.158 = INTEGER: 0

SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.51.118 = INTEGER: 0

  1. В строках нужно сделать выборку по каждой строке, начиная с числа 72, например 72.87.84.67.166.75.50.108.
  2. Каждое число которое идет через точку 72 и так далее нужно перевести из десятичного значения в шестнадцатеричное значение, 72 это 48, 87 это 57, используя hex(), что бы получилось 48.57.54.43.a6.ac.d4.e8

Если сделать без pandas, то получается так:

import re

re_str = r'72.\d*.\d*.\d*\d*.\d*.\d*.\d*.\d*'
first_str = 'SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.172.212.232 = INTEGER: 0'
all_re_list = re.findall(re_str, first_str)
re_list_to_str = " ".join(all_re_list)
re_str_to_list2 = re_list_to_str.split('.')
re_str_to_list_int = []
for i in re_str_to_list2:
    i = int(i)
    re_str_to_list_int.append(i)

re_str_to_list_hex = []
for i in re_str_to_list_int:
    a = hex(int(i))[2:]
    re_str_to_list_hex.append(a)

print('re_str_to_list_hex', re_str_to_list_hex[:])

Итог получается такой: re_str_to_list_hex ['48', '57', '54', '43', 'a6', 'ac', 'd4', 'e8']

Как все это сделать используя Pandas? Так как имеется много данных в табличном виде.


Ответы (1 шт):

Автор решения: Алексей Р

Здесь можно воспользоваться методом str.replace() с заменой через функцию. Сначала режем строки перед '.72' и помещаем в промежуточный фрейм в два столбца. Второй столбец обрабатываем str.replace(), заменяя все вхождения чисел после точки на их шестнадцатеричное представление. После чего склеиваем обе части строк.

df = pd.DataFrame({'data': ['SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.50.108 = INTEGER: 0',
                            'SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.50.158 = INTEGER: 0',
                            'SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.51.118 = INTEGER: 0']})
tmp = df.data.str.split('(?=\.72)', expand=True, regex=True, n=1)
df.data = tmp[0].add(tmp[1].str.replace(r'(?<=\.)\d+', lambda x: f'{int(x[0]):x}', regex=True))
print(df)

Результат:

                                                                                   data
0  SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.48.57.54.43.a6.4b.32.6c = INTEGER: 0
1  SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.48.57.54.43.a6.4b.32.9e = INTEGER: 0
2  SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.48.57.54.43.a6.4b.33.76 = INTEGER: 0

Если же нужно вытащить преобразованные числа в список, то можно так:

df = pd.DataFrame({'data': ['SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.50.108 = INTEGER: 0',
                            'SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.50.158 = INTEGER: 0',
                            'SNMPv2-SMI::enterprises.35265.1.22.3.1.1.14.1.8.72.87.84.67.166.75.51.118 = INTEGER: 0']})
tmp = df.data.str.split('(?=\.72)', expand=True, regex=True, n=1)[1].str.extractall(r'(?<=\.)(\d+)').apply(lambda x: f'{int(x[0]):x}', axis=1).unstack().agg(list, axis=1)
print(tmp)
0    [48, 57, 54, 43, a6, 4b, 32, 6c]
1    [48, 57, 54, 43, a6, 4b, 32, 9e]
2    [48, 57, 54, 43, a6, 4b, 33, 76]
dtype: object
→ Ссылка