Решение, которое довольно просто понять, отладить и гибко расширить, состоит в следующем:
Учтите, что ваши первоначальные названия продуктов содержатся в списке под названием strings
.
Тогда решением будет следующая строка :
mydf = pd.concat([pd.DataFrame([make_row(row, 4)], columns=['COL1', 'COL2', 'COL3', 'COL4']) for row in strings], ignore_index=True)
где мы определили функцию синтаксического анализа make_row
:
def make_row(string, num_cols):
cols = [item.strip() for item in string[2:].split('-')] # ignore numbering, split on hyphen and strip whitespace
if len(cols) < num_cols:
cols += [np.nan]*(num_cols - len(cols)) # fill with NaN missing values
return cols
Первая строка, определяющая cols
, также может быть просто cols = string.split('-')
, и в этом случае вы можете выполнить форматирование впоследствии с помощью:
mydf.applymap(lambda x: x if pd.isnull(x) else str.strip(x))
Теперь, в вашем случае, я вижу, что в некоторых названиях ваших продуктов есть дефис, и в этом случае вы можете захотеть «санировать» их заранее (или внутри make_row
, как вы хотите), с чем-то вроде :
strings = [item.replace('t-shirt', 'tshirt') for item in strings]
Пример ввода :
strings = ['1.one-two-three', '2. one-two', '3.one-two-three-four', '4.one - two -three -four ']
выход :
COL1 COL2 COL3 COL4
0 one two three NaN
1 one two NaN NaN
2 one two three four
3 one two three four
Вывод данных вопроса (после исправления опечатки для пункта 4):
COL1 COL2 COL3 COL4
0 star tshirt large red NaN
1 star tshirt large blue NaN
2 star tshirt small red NaN
3 beautiful rainbow skirt small NaN NaN
4 long maxwell logan jeans light blue 32L 28W
5 long maxwell logan jeans Dark blue 32L 28W
Edit:
Если вы дополнительно хотите «сгруппировать» элементы вместе, тогда вы можете:
a) Используйте sort_values
( pandas doc ) в столбце COL1 после получения кадра данных, как описано выше, чтобы просто отображать строки, соответствующие одному и тому же продукту, один за другим, или
b) используйте group_by
для фактического получения сгруппированного фрейма данных, подобного этому:
grouped_df = mydf.groupby("COL1")
Это позволит вам получить каждую группу следующим образом:
grouped_df.get_group("star tshirt")
Производит следующий вывод:
COL1 COL2 COL3 COL4
0 star tshirt large red NaN
1 star tshirt large blue NaN
2 star tshirt small red NaN