Как добавить столбец в фрейм данных pandas со значениями, основанными на совпадении значений в двух фреймах данных

#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?