2013-12-09 2 views
8

Вот мой pandas.DataFrame:Получить верхние большие значения из каждого столбца 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']) 

Я хочу, чтобы создать новый DataFrame, который будет содержать верхние 3 значения из каждого столбца моего dataDataFrame.

Вот ожидаемый результат:

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

Как я могу это сделать?

ответ

9

Создайте функцию, чтобы вернуться в первую тройку значения серии:

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

Применить его к вашему набору данных:

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

С NumPy вы можете получить массив топ-3 значений вдоль столбцов, как следует:

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

Вы можете преобразовать обратно в 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

Обратите внимание, что это решение имеет сложность сверхлинейную. –

1

Другие решения (на момент написания этого), отсортировать DataFrame с супер-линейной сложности на колонке, но это на самом деле может быть сделано с линейным временем в колонке.

первый, numpy.partition перегородки в к наименьшие элементов на к первых позиций (несортированным в противном случае). Чтобы получить к крупнейших элементов, мы можем использовать

import numpy as np 

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

В сочетании со словарем понимания, мы можем использовать:

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

Альтернативное решение панды:

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

Использование nlargest как

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 

где

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 
Смежные вопросы