Анализ полей, в которых тире соединяет несколько значений

#python #pandas

Вопрос:

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

ID код
1 A312B-D
2 BAFDA-BAFDC
3 BFD3-5
4 B3140-B3142

Я хочу проанализировать столбец кода со следующим выводом:

ID код
1 A312B A312C A312D
2 BAFDA BAFDB BAFDC
3 BFD3 BFD4 BFD5
4 B3140 B3141 B3142

Таким образом, основное правило состоит в том, что если исходное значение кода содержит 2 или более символов, содержит тире, и либо за тире следует одна буква или число (т. е. «XXXX1-3»), либо строка одинаковой длины до и после тире (т. е. «XXXX1-XXXX3»), то мы разделяем ее на отдельные значения, разделенные пробелом.

Потратил на это несколько часов, но не смог найти решения, надеюсь получить некоторую помощь.

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

1. Я ценю, что вы много работали над этим, но пока мы не увидим некоторые примеры вашего кода, трудно понять, с какой частью проблемы у вас возникли проблемы.

Ответ №1:

Вы можете использовать Панд apply с функцией ( expand в примере), использующей регулярное выражение, чтобы разделить код на группы захвата, и, используя преимущества уже существующих групп регулярных выражений, используйте группы как для определения того, является ли это буквой или цифрой, так и range для создания шаблона для этих символов.

 import pandas as pd
import re

d = {
    'id ': {0: 1, 1: 2, 2: 3, 3: 4},
    'code': {0: 'A312B-D', 1: 'BAFDA-BAFDC', 2: 'BFD3-5', 3: 'B3140-B3142'}
}

df = pd.DataFrame(d)
print(df)

regex = re.compile(r'(.*?)(d |[A-Z])-(.*?)(d |[A-Z])

Вывод из df

    id          code           code_ext
0    1      A312B-D  A312B A312C A312D
1    2  BAFDA-BAFDC  BAFDA BAFDB BAFDC
2    3       BFD3-5     BFD3 BFD4 BFD5
3    4  B3140-B3142  B3140 B3141 B3142
 


)

def expand(code):
m = regex.findall(code)
if m:
if m[0][1].isdigit():
new_range = [f'{m[0][0]}{num}' for num in range(int(m[0][1]), int(m[0][3]) 1)]
else:
new_range = [f'{m[0][0]}{chr(num)}' for num in range(ord(m[0][1]), ord(m[0][3]) 1)]

return " ".join(new_range)
return code

df['code_ext'] = df['code'].apply(expand)
print(df)
Вывод из df