У меня есть такой фрейм данных,
Payload Timestamp
3c313034393536353534303b31332e32333534313b303b302e303637313b302e303138313b332e33353b36322e31353338323e 2022-03-16 18:00:08
3c313034393536363134303b31332e32313134383b303b302e303637323b302e3031383b342e3632353b37332e34353133313e 2022-03-16 18:10:07
3c313034393536363734303b31332e31393630313b303b302e303637323b302e3031383b342e303132353b36322e3434323835 2022-03-16 18:20:08
3e 2022-03-16 18:20:11
3c313034393537353734303b31332e31303137343b303b302e3036373b302e303137393b342e383132353b37352e343931393e 2022-03-16 18:30:09
3c313034393538323934303b31332e30353934353b303b302e303636373b302e303137393b332e313337353b37352e37313830 2022-03-16 18:40:08
393e 2022-03-16 18:40:14
Теоретически я получаю данные (столбец полезной нагрузки) периодически каждые X минут (10 в этом примере). Но если сообщение слишком длинное, отправка разделяется.
Когда это разделение выполнено, сообщения отправляются практически одно за другим в считанные секунды, поэтому я хотел бы создать новый фрейм данных, в котором, если разница между столбцом и следующим меньше X секунд (60 секунд, например) столбец полезной нагрузки имеет объединенные данные. Что касается столбца времени, этот новый фрейм данных может показывать дату и время, которые оба разделяют без секунд.
Я хотел бы что-то вроде этого,
Payload Timestamp
3c313034393536353534303b31332e32333534313b303b302e303637313b302e303138313b332e33353b36322e31353338323e 2022-03-16 18:00
3c313034393536363134303b31332e32313134383b303b302e303637323b302e3031383b342e3632353b37332e34353133313e 2022-03-16 18:10
3c313034393536363734303b31332e31393630313b303b302e303637323b302e3031383b342e303132353b36322e34343238353e 2022-03-16 18:20
3c313034393537353734303b31332e31303137343b303b302e3036373b302e303137393b342e383132353b37352e343931393e 2022-03-16 18:30
3c313034393538323934303b31332e30353934353b303b302e303636373b302e303137393b332e313337353b37352e37313830393e 2022-03-16 18:40
Первое, что я думаю, что мне нужно сделать, это получить разницу между временами
df['time_dif'] = df['Timestamp'].diff()
Но я не уверен, что мне теперь делать. Как я могу сгруппировать это? Читая другие сообщения, я понимаю, что должен использовать group_by
, но я не могу достичь своей цели.
Я сделал несколько таких попыток:
fdf = df.groupby(['Timestamp',pd.Grouper(key = 'Timestamp', freq='1min')])
Кто-нибудь может мне помочь?
Благодарю вас!
Я предлагаю вам использовать что-то вроде:
df.reset_index(inplace=True)
df["Timestamp"] = pd.to_datetime(df["Timestamp"])
df.set_index("Timestamp", inplace=True)
newDf = df.groupby(pd.Grouper(freq = "1Min")).sum()
newDf[newDf["Payload"] != 0]
Отметка времени | Полезная нагрузка |
---|---|
2022-03-16 18:00:00 | 3c313034393536353534303b31332e32333534313b303b302e303637313b302e303138313b332e33353b36322e31353338323e |
2022-03-16 18:10:00 | 3c313034393536363134303b31332e32313134383b303b302e303637323b302e3031383b342e3632353b37332e34353133313e |
2022-03-16 18:20:00 | 3c313034393536363734303b31332e31393630313b303b302e303637323b302e3031383b342e303132353b36322e34343238353e |
2022-03-16 18:30:00 | 3c313034393537353734303b31332e31303137343b303b302e3036373b302e303137393b342e383132353b37352e343931393e |
2022-03-16 18:40:00 | 3c313034393538323934303b31332e30353934353b303b302e303636373b302e303137393b332e313337353b37352e37313830393e |
Обратите внимание, что в этом решении Timestamp
— это индекс newDf
. Итак, чтобы избавиться от индекса и изменить его на столбец, как это было раньше, просто используйте newDf.reset_index(inplace=True)
@Lleims Спасибо за ваш комментарий. Я предполагаю, что Payload
- это индекс вашего фрейма данных. Поэтому я отредактировал свой ответ в соответствии с вашим комментарием. И, конечно же, функцию sum
можно применять к строкам. В случае строк они будут добавляться друг к другу.
Попробуйте с resample
:
df["Timestamp"] = pd.to_datetime(df["Timestamp"])
output = df.resample("10min",on = "Timestamp")["Payload"].sum()
>>> output
Timestamp Payload
2022-03-16 18:00:00 3c313034393536353534303b31332e32333534313b303b302e303637313b302e303138313b332e33353b36322e31353338323e
2022-03-16 18:10:00 3c313034393536363134303b31332e32313134383b303b302e303637323b302e3031383b342e3632353b37332e34353133313e
2022-03-16 18:20:00 3c313034393536363734303b31332e31393630313b303b302e303637323b302e3031383b342e303132353b36322e34343238353e
2022-03-16 18:30:00 3c313034393537353734303b31332e31303137343b303b302e3036373b302e303137393b342e383132353b37352e343931393e
2022-03-16 18:40:00 3c313034393538323934303b31332e30353934353b303b302e303636373b302e303137393b332e313337353b37352e37313830393e
Если вы не хотите округлять до ближайших «10 минут», а вместо этого хотите использовать отличия от вашей первой метки времени, вы можете сделать:
output = (df.groupby(df["Timestamp"].diff().dt.total_seconds().gt(60).cumsum())
.agg({"Timestamp": "first", "Payload": "sum"})
)
Если сообщение приходит в 09:59, оно будет объединено с предыдущей отметкой времени.
@Corralien - Правильно, спасибо. Добавил альтернативу.
Вы также можете использовать dt.round('10T')
в качестве альтернативы. Проверьте мой ответ ;-)
@Corralien - Хороший. Вы также можете использовать .round
без .dt
!
Спасибо я этого не знал. Еще одно дополнение, если в коде Pandas :)
Вы можете использовать dt.round
. С dt.round
, если сообщение приходит раньше, оно не будет сгруппировано с предыдущим сообщением.
df.groupby(df['Timestamp'].dt.round('10T'))['Payload'].sum().reset_index()[df.columns]
# Output
Payload Timestamp
0 3c313034393536353534303b31332e32333534313b303b302e303637313b302e303138313b332e33353b36322e31353338323e 2022-03-16 18:00:00
1 3c313034393536363134303b31332e32313134383b303b302e303637323b302e3031383b342e3632353b37332e34353133313e 2022-03-16 18:10:00
2 3c313034393536363734303b31332e31393630313b303b302e303637323b302e3031383b342e303132353b36322e34343238353e 2022-03-16 18:20:00
3 3c313034393537353734303b31332e31303137343b303b302e3036373b302e303137393b342e383132353b37352e343931393e 2022-03-16 18:30:00
4 3c313034393538323934303b31332e30353934353b303b302e303636373b302e303137393b332e313337353b37352e37313830393e 2022-03-16 18:40:00
Это не работает для меня, последняя строка кода показывает ошибку. «Полезная нагрузка не существует», и я думаю, это потому, что ваш
sum()
и полезная нагрузка — это строка: S