#python #pandas
Вопрос:
Мне нужно разделить столбец под названием Creative, где каждая ячейка содержит образцы, такие как:
pn(2021)io(302)ta(Yes)pt(Blue)cn(John)cs(Doe)
Где каждый двухбуквенный код, предшествующий каждому пузырьковому разделу (), является заголовком нужного столбца и одинаков в каждой строке. Единственные данные, которые меняются, — это то, что находится внутри пузырьков. Я хочу, чтобы данные выглядели так:
pn | io | ta | Очки | cn | CS |
---|---|---|---|---|---|
2021 | 302 | ДА | Синий | Джон | Доу |
Я пытался
df[['Creative', 'Creative Size']] = df['Creative'].str.split('cs(',expand=True)
и
df['Creative Size'] = df['Creative Size'].str.replace(')','')
но произошла ошибка, ошибка: missing ), unterminated subpattern at position 2
, предполагая, что это как-то связано с регулярными выражениями.
Есть ли простой способ разделить их ? Спасибо.
Комментарии:
1. попробуйте это df[‘Креативный размер’] = df[‘Креативный размер’].str.замените(‘)’,»)
2. Оба ваших примера связаны с неправильным синтаксисом, например, df [[«Креативный», «Креативный размер»]] = df [«Креативный»]. str.split («cs (» , expand=True) определенно отсутствует апостроф и последняя закрывающая скобка
Ответ №1:
Используйте extract
с именованными группами захвата (см. Здесь):
import pandas as pd
# toy example
df = pd.DataFrame(data=[["pn(2021)io(302)ta(Yes)pt(Blue)cn(John)cs(Doe)"]], columns=["Creative"])
# extract with a named capturing group
res = df["Creative"].str.extract(
r"pn((?P<pn>d ))io((?P<io>d ))ta((?P<ta>w ))pt((?P<pt>w ))cn((?P<cn>w ))cs((?P<cs>w ))",
expand=True)
print(res)
Выход
pn io ta pt cn cs
0 2021 302 Yes Blue John Doe
Ответ №2:
Я бы использовал регулярное выражение для создания списка словарей с помощью понимания. Идея состоит в том, чтобы создать список словарей, каждый из которых представляет строки нужного фрейма данных, а затем построить из него фрейм данных. Я могу построить его в одном вложенном понимании:
import re
rows = [{r[0]:r[1] for r in re.findall(r'(w{2})((. ))', c)} for c in df['Creative']]
subtable = pd.DataFrame(rows)
for col in subtable.columns:
df[col] = subtable[col].values
В принципе, я регулярно выполняю поиск экземпляров ab(*)
и фиксирую двухбуквенный префикс и содержимое круглых скобок и сохраняю их в списке кортежей. Затем я создаю словарь из списка кортежей, каждый из которых по сути является строкой, подобной той, которую вы показываете в своем вопросе. Затем я помещаю их в фрейм данных и вставляю каждый из этих столбцов в исходный фрейм данных. Дайте мне знать, если это вас как-то смущает!
Дэвид
Ответ №3:
Попробуйте с extractall
:
names = df["Creative"].str.extractall("(.*?)(.*?)").loc[0][0].tolist()
output = df["Creative"].str.extractall("((.*?))").unstack()[0].set_axis(names, axis=1)
>>> output
pn io ta pt cn cs
0 2021 302 Yes Blue John Doe
1 2020 301 No Red Jane Doe
Вход df:
df = pd.DataFrame({"Creative": ["pn(2021)io(302)ta(Yes)pt(Blue)cn(John)cs(Doe)",
"pn(2020)io(301)ta(No)pt(Red)cn(Jane)cs(Doe)"]})
Ответ №4:
Мы можем использовать str.findall
для извлечения совпадающих пар имя-значение столбца
pd.DataFrame(map(dict, df['Creative'].str.findall(r'(w )((w )')))
pn io ta pt cn cs
0 2021 302 Yes Blue John Doe
Ответ №5:
Использование регулярных выражений, другой способ упаковки конечного кадра данных:
import re
import pandas as pd
txt = 'pn(2021)io(302)ta(Yes)pt(Blue)cn(John)cs(Doe)'
data = list(zip(*re.findall('([^(] )(([^)] ))', txt))
df = pd.DataFrame([data[1]], columns=data[0])