Как продублировать строки по разным id из одного столбца?
Работаю с файлом, загруженным в Jupyter Notebook.
Исходная таблица вида:
df = pd.DataFrame({'id':['1','2,3','4,5,6','7'],
'name':['Ann','Alex','Mark','John'],
'city':['M','L','R','M']})
Нужно из нее получить таблицу вида:
df2 = pd.DataFrame({'id':['1','2','3','4','5','6','7'],
'name':['Ann','Alex','Alex','Mark','Mark','Mark','John'],
'city':['M','L','L','R','R','R','M']})
Т.е., если в id указано несколько значений, то нужно данную строку продублировать по каждому из них. Чтобы в итоге в столбце id было указано только по одному значению.
Ответы (1 шт):
Автор решения: MaxU
→ Ссылка
Воспользуйтесь DataFrame.explode():
res = df.assign(id=df["id"].str.split(",")).explode("id")
результат:
In [350]: res
Out[350]:
id name city
0 1 Ann M
1 2 Alex L
1 3 Alex L
2 4 Mark R
2 5 Mark R
2 6 Mark R
3 7 John M
UPDATE: метод DataFrame.explode() появился в Pandas 0.25.0, для более старых вырсий можно воспользоваться функцией explode(df, lst_cols, fill_value='', preserve_index=False)
def explode(df, lst_cols, fill_value='', preserve_index=False):
# make sure `lst_cols` is list-alike
if (lst_cols is not None
and len(lst_cols) > 0
and not isinstance(lst_cols, (list, tuple, np.ndarray, pd.Series))):
lst_cols = [lst_cols]
# all columns except `lst_cols`
idx_cols = df.columns.difference(lst_cols)
# calculate lengths of lists
lens = df[lst_cols[0]].str.len()
# preserve original index values
idx = np.repeat(df.index.values, lens)
# create "exploded" DF
res = (pd.DataFrame({
col:np.repeat(df[col].values, lens)
for col in idx_cols},
index=idx)
.assign(**{col:np.concatenate(df.loc[lens>0, col].values)
for col in lst_cols}))
# append those rows that have empty lists
if (lens == 0).any():
# at least one list in cells is empty
res = (res.append(df.loc[lens==0, idx_cols], sort=False)
.fillna(fill_value))
# revert the original index order
res = res.sort_index()
# reset index if requested
if not preserve_index:
res = res.reset_index(drop=True)
return res
PS по ссылке выше на оригинальный пост можно найти примеры использования данной функции...