#python #pandas
#python #pandas
Вопрос:
У меня есть фрейм данных, который содержит аварии автомобилей, они могут быть «L» для легких или «S» для сильных:
|car_id|type_acc|datetime_acc|
------------------------------
| 1 | L | 2020-01-01 |
| 1 | L | 2020-01-05 |
| 1 | S | 2020-01-07 |
| 1 | L | 2020-01-09 |
| 2 | L | 2020-01-04 |
| 2 | L | 2020-01-10 |
| 2 | L | 2020-01-12 |
Я хотел бы получить столбец, который считается до первого ‘S’ и делит количество вхождений между максимальным и минимальным ‘L’, поэтому результат будет:
|car_id|freq_acc|
-----------------
| 1 | 2 | # 4 days (from 1 to 5) / 2 number of 'L' before first 'S'
| 2 | 8 | # 8 days(from 4 to 12) and no 'S'
Возможно ли такое? Спасибо
Ответ №1:
Вы можете использовать np.ptp для вычисления максимальной и минимальной разницы:
# find first by S by car_id
df['eq_s'] = df.groupby('car_id')['type_acc'].transform(lambda x: x.eq('S').cumsum())
# compute stats based on previous computation, keeping only the first group
groups = df[df['eq_s'].eq(0)].groupby(['car_id']).agg({'datetime_acc': np.ptp}).reset_index()
# rename
res = groups.rename(columns={'datetime_acc': 'freq_acc'})
print(res)
Вывод
car_id freq_acc
0 1 4 days
1 2 8 days
Прежде чем что-либо делать, убедитесь, что datetime_acc является столбцом datetime, выполнив:
df['datetime_acc'] = pd.to_datetime(df['datetime_acc'])
Первый шаг:
# find first by S by car_id
df['eq_s'] = df.groupby('car_id')['type_acc'].transform(lambda x: x.eq('S').cumsum())
создаст новый столбец, в котором единственными представляющими интерес значениями являются 0, то есть те, которые находятся перед первым S. На втором шаге мы сохраняем только эти значения и выполняем стандартный groupby:
# compute stats based on previous computation, keeping only the first group
groups = df[df['eq_s'].eq(0)].groupby(['car_id']).agg({'datetime_acc': np.ptp}).reset_index()