2013-12-09 20 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将包含从我dataDataFrame的每列前3位的值。

这里是一个预期的输出:

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) 

您可以转换回数据帧:

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

的其他解决方案(在写这篇的时间),排序与超线性复杂列数据框,但它其实是可以用每列线性的时间内完成。

第一,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