pandas: перевести часть строки из десятичного в шестнадцатеричное счисление
Имеется таблица, в которой есть столбец со строковыми данными. В каждой строке необходимо перевести часть строки из десятичного значение в шестнадцатеричное.
- Имеются строки в столбцах.
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
- В строках нужно сделать выборку по каждой строке, начиная с числа 72, например 72.87.84.67.166.75.50.108.
- Каждое число которое идет через точку 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