2015-09-28 2 views
0

Учитывая мультииндексный фрейм данных Pandas, df2, я хочу вычислить разницу в каждой строке из строки выше в каждой категории.Как вычесть строки в группах данных?

import pandas as pd 
inner = ('a','b','c') 
cols = ('A','B','C','D') 
df1=pd.DataFrame(np.random.randn(3,4), index=inner, columns=cols) 
df2=pd.concat([df1,df1],keys=['X','Y']) 

df2:

   A  B    C   D 
X a -0.391804 -0.307916 -0.265643 -0.222193 
    b -0.142498 -1.389972 1.060328 1.207945 
    c 1.156881 1.596382 0.620923 0.592739 
Y a -0.391804 -0.307916 -0.265643 -0.222193 
    b -0.142498 -1.389972 1.060328 1.207945 
    c 1.156881 1.596382 0.620923 0.592739 

Вот что я пробовал:

df2.groupby(level=[0]).apply(lambda x: df2.loc[x.index[:-1]-df2.loc[x.index[1:]]]) 

Но это будет получить неверный результат dataframe с тремя-Листики индексов.

   A   B   C   D 
X X a -0.391804 -0.307916 -0.265643 -0.222193 
     b -0.142498 -1.389972 1.060328 1.207945 
Y Y a -0.391804 -0.307916 -0.265643 -0.222193 
     b -0.142498 -1.389972 1.060328 1.207945 
+0

если вы 'groupby' на всех уровнях вашего индекса, каждая группа будет иметь только 1 строку в нем, так что ваши результаты всех' NaNs' делает смысл. –

+1

это поможет понять, что вы пытаетесь выполнить, если вы разместили ожидаемый результат –

ответ

2

Вы не можете группировать все уровни вашего индекса b/c, тогда каждая группа будет иметь только 1 строку, и вычесть ее нечего. Кроме того, использование неслучайных данных (вычитание не интуитивное) давайте изменила ваш пример немного:

import pandas 
import numpy as np 

df = pandas.DataFrame(
    data={'A': np.arange(8) ** 2, 'B': np.arange(8) ** 0.5}, 
    index=pandas.MultiIndex.from_product([list('XY'), list('abcd')]) 
) 
df 
#  A   B 
# X a 0 0.000000 
# b 1 1.000000 
# c 4 1.414214 
# d 9 1.732051 
# Y a 16 2.000000 
# b 25 2.236068 
# c 36 2.449490 
# d 49 2.645751 

Так что, если мы только группа вдоль подмножества уровней индекса, мы можем использовать метод shift из dataframe, чтобы получить прокатный разницу внутри каждой группы:

df.groupby(level=[0]).transform(lambda g: g.shift(-1) - g) 

#  A   B 
# X a 1 1.000000 
# b 3 0.414214 
# c 5 0.317837 
# d NaN  NaN 
# Y a 9 0.236068 
# b 11 0.213422 
# c 13 0.196262 
# d NaN  NaN 
Смежные вопросы