#python #pandas #dataframe
#python #pandas #фрейм данных
Вопрос:
Я работаю с двумя фреймами данных pandas. Один содержит данные о производительности разных серверов за каждый час и выглядит примерно так:
Дата | время | имя_сервера | Процессор | Память |
---|---|---|---|---|
2020-10-25 | 300 | server1 | 90.2 | 64.4 |
2020-10-25 | 300 | server2 | 50.4 | 23.3 |
В этом случае «300» в столбце «время» означает 3 часа ночи.
Второй фрейм данных содержит данные об ошибках для разных серверов и выглядит примерно так:
имя_сервера | временная метка |
---|---|
server1 | 2020-10-25 00:45:04 |
server2 | 2020-10-25 03:45:04 |
Я хотел бы, чтобы в первый фрейм данных был добавлен столбец с показателями производительности, который указывает для каждого сервера за каждый час, если в это время произошла ошибка. Пожалуйста, обратите внимание, что ошибка, возникшая в 3:45 утра, должна быть присвоена строке для 3am для соответствующего сервера. Это должно выглядеть примерно так:
Дата | время | имя_сервера | Процессор | Память | ошибка |
---|---|---|---|---|---|
2020-10-25 | 300 | server1 | 90.2 | 64.4 | 0 |
2020-10-25 | 300 | server2 | 50.4 | 23.3 | 1 |
В этом случае «1» в столбце «ошибка» будет означать, что в это время на сервере произошла ошибка.
Я уже пытался объединить фреймы данных по дате, времени и имя_сервера и многие другие подходы, но я просто не получаю желаемых результатов.
Комментарии:
1. df= pd.merge(слева, справа, on=»имя_сервера»?
2. 1. во втором df преобразуйте временную метку в ваш 1-й формат df. 2. затем для второго df
groupby(server_name, new_timestamp).count()
, 3. объединить результат с первым df по имя_сервера и времени3. Я не хочу подсчитывать ошибки для сервера в определенное время, мне нужна двоичная классификация, где «1» означает, что в это конкретное время на этом сервере произошла ошибка, а «0» будет означать, что ошибки не было.
Ответ №1:
Предполагая df1
, что это ваш первый фрейм данных, а df2
второй — второй, вы можете добавить столбец метки df1
времени, добавив столбец Date
and time
, а затем использовать merge_asof
для привязки каждой строки для второго фрейма к строке из этого измененного фрейма данных.
Оттуда вы можете объединить этот новый фрейм данных с первым, и a groupby
и count
должен дать ожидаемый результат.
Возможный код:
df3 = pd.merge_asof(df2, df1.assign(timestamp=df1['Date']
pd.to_timedelta(df1['time']/100, 'H')),
by='server_name', on='timestamp',
tolerance=pd.Timedelta('1H'))
print(df3)
result = df1.merge(df3[['server_name', 'timestamp', 'Date', 'time']], 'left',
on=['server_name', 'Date', 'time']
).groupby(['server_name', 'Date', 'time', 'CPU', 'Memory']
).count().rename(columns={'timestamp': 'error'}
).reset_index()
С вашими данными он выдает ожидаемое:
server_name Date time CPU Memory error
0 server1 2020-10-25 300 90.2 64.4 0
1 server2 2020-10-25 300 50.4 23.3 1
Комментарии:
1. Спасибо за ответ! Мне пришлось преобразовать значения даты и времени в datetime и отсортировать фреймы данных, но в итоге код скомпилировался без ошибок. Но результат df содержит только строки, в которых произошла хотя бы одна ошибка. Мне также нужны те, в которых не возникло ошибки, что означает, что результирующий фрейм данных должен быть таким же большим, как первый фрейм данных с показателями производительности. Мне также пришлось удалить показатели производительности из groupby-предложения из-за ошибки ключа. Может быть, именно по этой причине он возвращает только строки с числом> 0?