#python #python-3.x #pandas
Вопрос:
Всем привет, мне нужна помощь, чтобы объединить столбцы, содержащие, когда внутри есть определенное значение grep.
Вот пример
Species COL1 COL2 COL3 COL4 COL5
SPf_1 4 f_G1 None None None
SP1 9 -_Haploviric -_unclassified f_G3 None
SP1 36 k_Orthorn f_G7 None None
SP2 90 k_Orthorn f_G3 p_Pisuvi None
SP3 32 None None None f_83
SP3 2 -_Ribovi Cattus None None
SP4 89 None None None None
а затем я хотел бы добавить новый столбец под названием F_COL, в котором я помещаю для каждой строки содержимое ячейки с f_ pattern
буквой «а». Примечание (мне нужно проверить только COL1-5
столбцы, но не Species
столбцы, которые также могут иметь шаблоны f_).
Я должен получить :
Species COL1 COL2 COL3 COL4 COL5 F_COL
SPf_1 4 f_G1 None None None f_G1
SP1 9 -_Haploviric -_unclassified f_G3 None f_G3
SP1 36 k_Orthorn f_G7 None None f_G7
SP2 90 k_Orthorn f_G3 p_Pisuvi None f_G3
SP3 32 None None None f_83 f_83
SP3 2 -_Ribovi Cattus None None NA
SP4 89 None None None None NA
У кого-нибудь есть идея, пожалуйста ?
Вот данные в формате словаря :
{'Species': {0: 'SPf_1', 1: 'SP1', 2: 'SP1', 3: 'SP2', 4: 'SP3', 5: 'SP3', 6: 'SP4'}, 'COL1': {0: 4, 1: 9, 2: 36, 3: 90, 4: 32, 5: 2, 6: 89}, 'COL2': {0: 'f_G1', 1: '-_Haploviric-', 2: 'k_Orthorn', 3: 'k_Orthorn', 4: 'None', 5: '-_Ribovi', 6: 'None'}, 'COL3': {0: 'None', 1: '_unclassified', 2: 'f_G7', 3: 'f_G3', 4: 'None', 5: 'Cattus', 6: 'None'}, 'COL4': {0: 'None', 1: 'f_G3', 2: 'None', 3: 'p_Pisuvi', 4: 'None', 5: 'None', 6: 'None'}, 'COL5': {0: 'None', 1: 'None', 2: 'None', 3: 'None', 4: 'f_83', 5: 'None', 6: 'None'}}
Комментарии:
1. Может ли быть несколько ячеек в одной строке, содержащих
f_pattern
одинаковые значения?2. Нет, для каждой строки есть один уникальный f_pattern
Ответ №1:
Давайте filter
и stack
столбцы от COL1
до COL5
, затем extract
f_pattern
строки, за которыми следует groupby
first
на level=0
df.filter(regex='COL[1-5]').stack()
.str.extract(r'^(f_.*)', expand=False).groupby(level=0).first()
0 f_G1
1 f_G3
2 f_G7
3 f_G3
4 f_83
5 None
6 None
dtype: object
Комментарии:
1. Хорошо, но, может быть, регулярное выражение не нужно
^
. Не уверен, что ОП имел в виду, что это должно начинаться сf_
.2. Спасибо @tdy, вы правы, мы могли бы удалить начало утверждения строки 🙂
Ответ №2:
import re
def get_f_pattern(row):
for value in row.values:
if isinstance(value, str) and re.match(r'f_w{2}', value):
return value
return 'NA'
df['F_COL'] = df.apply(get_f_pattern, axis=1)
df
Species COL1 COL2 COL3 COL4 COL5 F_COL
0 SPf_1 4 f_G1 None None None f_G1
1 SP1 9 -_Haploviric- _unclassified f_G3 None f_G3
2 SP1 36 k_Orthorn f_G7 None None f_G7
3 SP2 90 k_Orthorn f_G3 p_Pisuvi None f_G3
4 SP3 32 None None None f_83 f_83
5 SP3 2 -_Ribovi Cattus None None NA
6 SP4 89 None None None None NA
Это создает функцию, которая, учитывая строку, пробегает все ее значение и возвращает первый f_pattern, которому она соответствует, в противном случае «NA»
Затем мы запускаем .apply
, axis=1
чтобы сказать пандам применить эту функцию ко всем строкам и присвоить результат F_COL
Комментарии:
1. В этом случае вам следует просто заменить его любой проверкой, соответствующей шаблону
r'f_w '
, илиvalue.startswith('f_')