Ответ 1
что-то вроде этого:
df3 = pd.concat((df1, df2))
df3.groupby(df3.index).mean()
# col
# a 1
# b 3
# c 4
# d 6
или наоборот, как в ответе @unutbu:
pd.concat((df1, df2), axis=1).mean(axis=1)
У меня есть набор DataFrames с числовыми значениями и частично перекрывающимися индексами. Я хотел бы объединить их, принять среднее значение, если индекс имеет место в более чем одном DataFrame.
import pandas as pd
import numpy as np
df1 = pd.DataFrame([1,2,3], columns=['col'], index=['a','b','c'])
df2 = pd.DataFrame([4,5,6], columns=['col'], index=['b','c','d'])
Это дает мне два DataFrames:
col col
a 1 b 4
b 2 c 5
c 3 d 6
Теперь я хотел бы объединить DataFrames и принять среднее значение для каждого индекса (если это применимо, т.е. если оно встречается более одного раза).
Должно выглядеть так:
col
a 1
b 3
c 4
d 6
Могу ли я сделать это с помощью некоторого расширенного слияния/присоединения?
что-то вроде этого:
df3 = pd.concat((df1, df2))
df3.groupby(df3.index).mean()
# col
# a 1
# b 3
# c 4
# d 6
или наоборот, как в ответе @unutbu:
pd.concat((df1, df2), axis=1).mean(axis=1)
In [22]: pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1)
Out[23]:
a 1
b 3
c 4
d 6
dtype: float64
Что касается римского вопроса, я нахожу IPython %timeit
команду удобного способа сравнения кода:
In [28]: %timeit df3 = pd.concat((df1, df2)); df3.groupby(df3.index).mean()
1000 loops, best of 3: 617 µs per loop
In [29]: %timeit pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1)
1000 loops, best of 3: 577 µs per loop
In [39]: %timeit pd.concat((df1, df2), axis=1).mean(axis=1)
1000 loops, best of 3: 524 µs per loop
В этом случае pd.concat(...).mean(...)
оказывается немного быстрее. Но на самом деле мы должны тестировать более крупные данные, чтобы получить более значимый ориентир.
Кстати, если вы не хотите устанавливать IPython, эквивалентные тесты можно запустить с помощью Python timeit
module. Это требует немного больше настроек. В docs есть несколько примеров, показывающих, как это сделать.
Обратите внимание, что если df1
или df2
должны иметь повторяющиеся записи в своем индексе, например:
N = 1000
df1 = pd.DataFrame([1,2,3]*N, columns=['col'], index=['a','b','c']*N)
df2 = pd.DataFrame([4,5,6]*N, columns=['col'], index=['b','c','d']*N)
то эти три ответа дают разные результаты:
In [56]: df3 = pd.concat((df1, df2)); df3.groupby(df3.index).mean()
Out[56]:
col
a 1
b 3
c 4
d 6
pd.merge
, вероятно, не дает желаемого ответа:
In [58]: len(pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1))
Out[58]: 2002000
Пока pd.concat((df1, df2), axis=1)
вызывает значение ValueError:
In [48]: pd.concat((df1, df2), axis=1)
ValueError: cannot reindex from a duplicate axis