Добавление фреймов данных по индексу, удаление, если индекс отсутствует

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Допустим, у меня есть два фрейма данных, которые выглядят следующим образом:

 df1 =
                  t   val
2019-08-22 02:00:00   0.1
2019-08-24 02:00:00   0.2
2019-08-26 02:00:00   0.3
2019-08-28 02:00:00   0.4
2019-08-30 02:00:00   0.5

df2 =    
                  t   val
2019-08-24 02:00:00   0.3
2019-08-26 02:00:00   0.4
2019-08-28 02:00:00   0.5
2019-08-30 02:00:00   0.6
  

Если бы они были одинакового размера, я мог бы просто сделать это, чтобы добавить значения относительно индекса t :

 df_sum = df1.set_index('t')   df2.set_index('t')
  

Однако в этом случае df2 не так много строк, df1 чтобы это не сработало, и я получу несколько строк NaN (по крайней мере, это то, что я получаю). Итак, есть ли какой-либо способ, при котором он просто добавляет фреймы данных в соответствии с индексом, а затем просто удаляет строки, которые не существуют в обоих? В свою очередь, в результате получается фрейм данных с тем же количеством строк, что и фрейм с наименьшим числом?

Ответ №1:

Первая идея — использовать слияние с внутренними столбцами объединения и суммы по умолчанию:

 df = df1.merge(df2, on='t').set_index('t').sum(axis=1).to_frame('val')
print (df)
                     val
t                       
2019-08-24 02:00:00  0.5
2019-08-26 02:00:00  0.7
2019-08-28 02:00:00  0.9
2019-08-30 02:00:00  1.1
  

Или использовать Index.intersection и выбирать только строки в обоих DataFrame с помощью DataFrame.loc :

 df11 = df1.set_index('t') 
df22 = df2.set_index('t')
idx = df11.index.intersection(df22.index)

df = df11.loc[idx]   df22.loc[idx]
print (df)
                     val
t                       
2019-08-24 02:00:00  0.5
2019-08-26 02:00:00  0.7
2019-08-28 02:00:00  0.9
2019-08-30 02:00:00  1.1
  

Если в исходных данных нет ошибочных значений, возможно добавить DataFrame.dropna для удаления только добавленные пропущенные значения:

 df = (df1.set_index('t')   df2.set_index('t')).dropna()
print (df)
                     val
t                       
2019-08-24 02:00:00  0.5
2019-08-26 02:00:00  0.7
2019-08-28 02:00:00  0.9
2019-08-30 02:00:00  1.1
  

Комментарии:

1. Последний, похоже, лучше всего подходит для моего случая. Поскольку мой код уже генерирует строки значений NaN при объединении фреймов данных, это кажется самым простым, поскольку именно эти строки в любом случае необходимо удалить.