Имея
car_id | скорость | раздел | |
---|---|---|---|
0 | 1 | 10 | а |
1 | 1 | 10 | б |
2 | 1 | 30 | с |
3 | 1 | 10 | |
4 | 2 | 10 | е |
5 | 2 | 0 | ф |
6 | 2 | 10 | грамм |
7 | 3 | 0 | час |
Мне нужна объединенная строка в двух столбцах, один из которых содержит разделы, если скорость <= 10 (legal_speed), а другие (незаконная_скорость). Значения со скоростью 0 должны быть пустой строкой:
car_id | Legal_speed | нелегальная_скорость | |
---|---|---|---|
0 | 1 | а, б, г | с |
1 | 2 | е, г | |
2 | 3 |
я пытался
df.groupby('car_id').agg(list)
но там пока не тихо
@Ch3steR извините, вы правы, редактирую
Вот решение, использующее np.select
и pivot
:
df['x'] = np.select([df['speed'] > 10, df['speed'] == 0], ['illegal_speed', 'na'], default='legal_speed')
new_df = df.pivot(values='section', columns='x').groupby(df['car_id']).apply(lambda g: g.apply(lambda col: col.dropna().tolist()).str.join(', ')).reset_index().rename_axis(None, axis=1)
Выход:
>>> new_df
car_id illegal_speed legal_speed na
0 1 c a, b, d
1 2 e, g f
2 3 h
Вот еще один вариант, более элегантный, хотя и немного более длинный:
df['x'] = np.select([df['speed'] > 10, df['speed'] == 0], ['illegal_speed', 'na'], default='legal_speed')
new_df = df.groupby('car_id').apply(lambda g: g.groupby('x')['section'].agg(list).str.join(', ')).unstack().fillna('').reset_index().rename_axis(None, axis=1)
Разделите столбец speed
на метки legal
и illegal
, затем сгруппируйте фрейм данных по car_id
и меткам и агрегируйте section
, используя join
:
s = pd.cut(df['speed'], [0, 10, np.inf], labels=['legal', 'illegal'])
df.groupby(['car_id', s])['section'].agg(', '.join).unstack()
Результат
speed legal illegal
car_id
1 a, b, d c
2 e, g NaN
3 NaN NaN
Для
car_id
2legal_speed
должно бытьe, g
, верно?