2013-12-09 17 views
8

Đây là tôi pandas.DataFrame:Nhận đỉnh giá trị lớn nhất từ ​​mỗi cột của 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']) 

Tôi muốn tạo ra một DataFrame mới sẽ chứa 3 giá trị hàng đầu từ mỗi cột của data tôi DataFrame.

Dưới đây là một kết quả mong muốn:

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

Làm thế nào tôi có thể làm điều đó?

Trả lời

9

Tạo một chức năng để trả lại top ba các giá trị của một chuỗi:

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

Áp dụng nó vào tập dữ liệu của bạn:

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

Với NumPy bạn có thể nhận mảng của top 3-giá trị dọc theo cột như sau:

>>> 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) 

Bạn có thể chuyển đổi trở lại 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

Lưu ý rằng giải pháp này có siêu tuyến tính phức tạp. –

1

Các giải pháp khác (tại thời điểm viết bài này), sắp xếp các DataFrame với siêu tuyến tính phức tạp mỗi cột, nhưng nó thực sự có thể được thực hiện với thời gian tuyến tính cho mỗi cột.

đầu tiên, numpy.partition phân vùng các k yếu tố nhỏ nhất tại k vị trí đầu tiên (không được phân loại khác). Để có được k yếu tố lớn nhất, chúng ta có thể sử dụng

import numpy as np 

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

Kết hợp điều này với sự hiểu biết từ điển, chúng ta có thể sử dụng:

>>> 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

Alternative giải pháp gấu trúc:

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

Sử dụng nlargest như

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 

nơi

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 
Các vấn đề liên quan