2013-12-09 11 views
8

Oto moja pandas.DataFrame:uzyskać Top największe wartości z każdej kolumnie pandas.DataFrame

import pandas as pd 
data = pd.DataFrame({ 
    'first': [40, 32, 56, 12, 89], 
    'second': [13, 45, 76, 19, 45], 
    'third': [98, 56, 87, 12, 67] 
}, index = ['first', 'second', 'third', 'fourth', 'fifth']) 

Chcę utworzyć nowy DataFrame który będzie zawierał 3 najlepsze wartości z poszczególnych kolumn mojego dataDataFrame.

Oto oczekiwany wynik:

first second third 
0  89  76  98 
1  56  45  87 
2  40  45  67 

W jaki sposób można to zrobić?

Odpowiedz

9

Tworzenie funkcji, aby powrócić do pierwszej trójki wartości serii:

def sorted(s, num): 
    tmp = s.sort_values(ascending=False)[:num] # earlier s.order(..) 
    tmp.index = range(num) 
    return tmp 

Zastosuj go do zestawu danych:

In [1]: data.apply(lambda x: sorted(x, 3)) 
Out[1]: 
    first second third 
0  89  76  98 
1  56  45  87 
2  40  45  67 
3

Z numpy można uzyskać tablicę najwyższej 3 wartości wzdłuż kolumn, jak następuje:

>>> import numpy as np 
>>> col_ind = np.argsort(data.values, axis=0)[::-1,:] 
>>> ind_to_take = col_ind[:3,:] + np.arange(data.shape[1])*data.shape[0] 
>>> np.take(data.values.T, ind_to_take) 
array([[89, 76, 98], 
     [56, 45, 87], 
     [40, 45, 67]], dtype=int64) 

można przekształcić z powrotem do DataFrame:

>>> pd.DataFrame(_, columns = data.columns, index=data.index[:3]) 
     first second third 
One  89  76  98 
Two  56  45  87 
Three  40  45  67 
+0

Zauważ, że to rozwiązanie ma superlinear złożoności. –

1

Inne rozwiązania (w momencie pisania tego), sortowania DataFrame ze złożoności super liniowego jednej kolumnie, ale może rzeczywiście być wykonane w czasie liniowym na kolumnie.

pierwszy numpy.partition do partycji K najmniejszych elementów na K pierwszej pozycji (nieposortowane inaczej). Aby uzyskać k największe elementy, możemy użyć

import numpy as np 

-np.partition(-v, k)[: k] 

Łącząc to z słowniku zrozumienia, możemy użyć:

>>> pd.DataFrame({c: -np.partition(-data[c], 3)[: 3] for c in data.columns}) 
    first second third 
0 89 76 98 
1 56 45 87 
2 40 45 67 
0

Alternatywne rozwiązanie pandy:

In [6]: N = 3 

In [7]: pd.DataFrame([df[c].nlargest(N).values.tolist() for c in df.columns], 
    ...:    index=df.columns, 
    ...:    columns=['{}_largest'.format(i) for i in range(1, N+1)]).T 
    ...: 
Out[7]: 
      first second third 
1_largest  89  76  98 
2_largest  56  45  87 
3_largest  40  45  67 
0

Zastosowanie nlargest jak

In [1594]: pd.DataFrame({c: data[c].nlargest(3).values for c in data}) 
Out[1594]: 
    first second third 
0  89  76  98 
1  56  45  87 
2  40  45  67 

gdzie

In [1603]: data 
Out[1603]: 
     first second third 
first  40  13  98 
second  32  45  56 
third  56  76  87 
fourth  12  19  12 
fifth  89  45  67 
Powiązane problemy