2015-05-19 15 views
5

Mam 2 ramki danych. chciałbym nadawać operację podzielićPodziel jedną ramkę danych pandy według drugiej - Ignoruj ​​kolumny indeksu z szacunkiem

df1= pd.DataFrame([[1.,2.,3.,4.], [5.,6.,7.,8.], [9.,10.,11.,12.]], 
        columns=['A','B','C','D'], index=['x','y','z']) 

df2= pd.DataFrame([[0.,1.,2.,3.]], columns=['A','B','D','C'], index=['q']) 

zauważyć, że kolumny są ustawione nieco inaczej w DF2.

Chciałbym podzielić df1 przez df2, gdzie rząd jest nadawany, ale etykiety kolumn są przestrzegane.

A B C D 
x 1 2 3 4 
y 5 6 7 8 
z 9 10 11 12 


    A B D C 
q 0 1 2 3 

To byłoby złe.

df1.values/df2.values 

[[   inf 2.   1.5   1.33333333] 
[   inf 6.   3.5   2.66666667] 
[   inf 10.   5.5   4.  ]] 

odpowiedzi pragnę to:

A B C  D 
x inf 2 1  2 
y inf 6 2.33 4 
z inf 10 3.66 6 

Odpowiedz

2

Po podzieleniu przez Series (wybierając że jeden wiersz drugiego dataframe), pandy będzie wyrównać tę serię na kolumnach pierwszej dataframe, dając pożądany rezultat:

In [75]: df1/df2.loc['q'] 
Out[75]: 
    A B   C D 
x inf 2 1.000000 2 
y inf 6 2.333333 4 
z inf 10 3.666667 6 

Jeśli nie wiesz/nie chcesz używać nazwy tego wiersza, możesz użyć squeeze, aby przekształcić jednokolumnową ramkę danych w serię: df1/df2.squeeze() (patrz odpowiedź @EdChum).

+0

bardzo ładnie i zwięźle +1 – EdChum

1

może być, można zamówić df2 kolumny same z df1 a następnie podzielić na wartościach

In [53]: df1.values/df2[df1.columns].values 
Out[53]: 
array([[   inf, 2.  , 1.  , 2.  ], 
     [   inf, 6.  , 2.33333333, 4.  ], 
     [   inf, 10.  , 3.66666667, 6.  ]]) 
1

Można zmienić kolejność kolumn, a następnie zadzwoń pod numer squeeze, aby spłaszczyć tablicę, a następnie zadzwoń pod numer div:

In [114]: 

df1= pd.DataFrame([[1.,2.,3.,4.],[5.,6.,7.,8.],[9.,10.,11.,12.]] ,columns = ['A','B','C','D'], index = ['x','y','z']) 
df2= pd.DataFrame([[0.,1.,2.,3.]] ,columns = ['A','B','D','C'], index = ['q']) ​ 
df1.div(df2.ix[:,df1.columns].squeeze()) 

Out[114]: 
    A B   C D 
x inf 2 1.000000 2 
y inf 6 2.333333 4 
z inf 10 3.666667 6 

df1/df2.ix[:,df1.columns].squeeze() działa również ale @ odpowiedź Joris jest znacznie ładniejszy

EDIT

Jak podkreślił @joris zmiana kolejności kolumny jest niepotrzebny jak pandy będą naturalnie wyrównać przed kolumnami tak więc:

df1.div(df2squeeze()) 

lub

df1./df2squeeze() 

będzie działać

+0

dzięki za uczenie mnie .squeeze() – Dickster

+1

@EdChum nie potrzebujesz części '.ix [:, df1.columns]' podczas używania 'div', ponieważ to wyrównuje indeksy automatycznie: po prostu' df1.div (df2.squeeze()) 'działa również (co jest również miłym rozwiązaniem!) – joris

+1

@joris tak nadto przemilczało to, lubię fantazyjne indeksowanie za dużo, zaktualizuję, dzięki – EdChum