#python #pandas #dataframe
#python #pandas #dataframe
Вопрос:
У меня есть фрейм данных продуктов, для которых у меня есть их входные и выходные данные. И я хочу сделать скользящее окно продолжительностью 30 минут, чтобы посмотреть, поступал ли продукт за эти 30 минут. Я думал использовать groupby, а затем отфильтровать эти группы, чтобы получить только те, которые у них есть in (1) и out (0).
Но, возможно, есть лучший способ сделать это, о котором я не подумал.
Пример:
code timestamp in_out
0 104 2018-12-18 16:15:00 1
1 105 2018-12-18 16:15:00 1
2 105 2018-12-18 16:35:00 0
3 107 2018-12-19 16:15:00 1
4 104 2019-01-13 10:00:00 0
5 502 2018-12-18 16:15:00 0
Редактировать:
Код, о котором я говорил groupby, является:
time1 = df.iloc[0]['timestamp']
time1end = time1 timedelta(minutes=30)
grp1 = df[(df['timestamp'] >= time1) amp; (df['timestamp'] <= time1end)]
grp1.groupby(by='subject_code').filter(lambda x: len(x) > 1)
Комментарии:
1. можете ли вы предоставить фрагмент кода с groupby, о котором вы говорите?
2. @Laleh Я опубликовал это при редактировании поста, я не публиковал это раньше, потому что я думаю, что это неправильно, потому что снова та же проблема, как сгруппировать 0 и 1 ‘in_out’.
3. тогда почему вы группируете по времени? разве мы не должны смотреть на каждый код и видеть, входят ли они, а затем выходят, если разница во времени составляет менее 30 минут?
4. Потому что мне нужно составить формулу, чтобы увидеть за эти 30 минут, сколько продуктов поступило и ушло, поэтому я подумал, что лучше посмотреть по времени, выполнив формулу, и проверить следующие 30 минут.
Ответ №1:
Я предлагаю вам сделать это следующим образом:
убедитесь, что временная метка соответствует формату datetime
df['timestamp'] = pd.to_datetime(df['timestamp'], infer_datetime_format=True)
Затем возьмите коды, которые вошли и вышли (если вы уверены, что каждый код повторялся ровно два раза, вы можете пропустить этот шаг)
df2 = df.groupby('code').filter(lambda x: x['in_out'].mean()==0.5)
Я фильтровал с помощью mean == 0.5, что означает «один раз в один раз», вы могли бы заменить его чем-то более умным
Теперь давайте решим проблему
df3 = df2.groupby('code')['timestamp'].diff().dropna()
Что делает этот фрагмент кода, для каждого кода он вычисляет разницу во времени, тогда вы можете использовать те, которые меньше 30 минут.
Комментарии:
1. Хотя есть проблема с
df.groupby('code').filter(lambda x: x['in_out'].mean()==0.5)
, потому что он получает только строки с одинаковой временной меткой. Итак, из 10 тысяч строк, которые у меня были, теперь у меня есть только 22. И 2 строки с кодом 0 и 1 имеют одинаковую временную метку2. Я не уверен, понял ли я вашу проблему. df.groupby(‘code’).filter(lambda x: x[‘in_out’].mean() ==0.5) не сохраняет строки с одинаковой временной меткой. Если вы запустите его на фрейме данных, который вы приводите в качестве примера, у вас будет это 0 104 2018-12-18 16:15:00 1 1 105 2018-12-18 16:15:00 1 2 105 2018-12-18 16:35:00 0 4 104 2019-01-13 10:00:00 0
3. Тогда, я полагаю, я что-то еще не так сделал с фреймом данных.