使用NumPy查找元组列表第二元素的中位数

时间:2015-08-05 15:26:09

标签: python numpy tuples

我们说我有一个元组列表,如下所示:

list = [(a,1), (b,3), (c,5)]

我的目标是使用元组'来获取元组列表中值的第一个元素。第二个要素。在上面的例子中,我想要一个b的输出,因为中位数是3.我尝试使用NumPy和下面的代码,但无济于事:

import numpy as np

list = [('a',1), ('b',3), ('c',5)]
np.median(list, key=lambda x:x[1])

3 个答案:

答案 0 :(得分:4)

np.median不接受任何名为key的参数。相反,您可以使用列表推导,仅从内部列表中获取第二个元素。示例 -

In [3]: l = [('a',1), ('b',3), ('c',5)]

In [4]: np.median([x[1] for x in l])
Out[4]: 3.0

In [5]: l = [('a',1), ('b',3), ('c',5), ('d',22),('e',11),('f',3)]

In [6]: np.median([x[1] for x in l])
Out[6]: 4.0

此外,如果不是为了示例目的,请不要使用list作为变量名称,它会隐藏内置函数list

答案 1 :(得分:4)

您可以像这样计算中位数:

np.median(dict(list).values()) 
# in Python 2.7; in Python 3.x it would be `np.median(list(dict(list_of_tuples).values()))`

首先将列表转换为字典,然后计算其值的中位数。

如果您想获得实际密钥,可以这样做:

dl = dict(list) #{'a': 1, 'b': 3, 'c': 5}

dl.keys()[dl.values().index(np.median(dl.values()))]

将打印'b'。假设中位数在列表中,如果不是,则会抛出ValueError。因此,您可以使用@Anand S Kumar的答案中的示例try/except来使用import numpy as np l = [('a',1), ('b',3), ('c',5), ('d',22),('e',11),('f',3)] # l = [('a',1), ('b',3), ('c',5)] dl = dict(l) try: print(dl.keys()[dl.values().index(np.median(dl.values()))]) except ValueError: print('The median is not in this list. Its value is ',np.median(dl.values())) print('The closest key is ', dl.keys()[min(dl.values(), key=lambda x:abs(x-np.median(dl.values())))])

mapreduce.job.running.map.limit

对于第一个列表,您将获得:

  

中位数不在此列表中。它的值是4.0

     

最近的关键是f

为您的示例打印:

  

B'/ P>

答案 2 :(得分:2)

np.median不接受某种“关键”参数,并且不会返回它找到的索引。此外,当存在偶数个项目(沿轴)时,它将返回2个中心项目的平均值。

但是np.partition median用于查找中心项,但确实采用了结构化数组字段名称。因此,如果我们将元组列表转换为结构化数组,我们可以轻松选择中间项。

清单:

In [1001]: ll
Out[1001]: [('a', 1), ('b', 3), ('c', 5)]

作为结构化数组:

In [1002]: la1 = np.array(ll,dtype='a1,i')
In [1003]: la1
Out[1003]: 
array([(b'a', 1), (b'b', 3), (b'c', 5)], 
     dtype=[('f0', 'S1'), ('f1', '<i4')])

我们可以使用:

获取中间项(大小为3的1
In [1115]: np.partition(la1, (1), order='f1')[[1]]
Out[1115]: 
array([(b'b', 3)], 
      dtype=[('f0', 'S1'), ('f1', '<i4')])

允许偶数项目(代码来自np.median):

def mymedian1(arr, field):
    # return the middle items of arr, selected by field
    sz = arr.shape[0]  # 1d for now
    if sz % 2 == 0:
        ind = ((sz // 2)-1, sz // 2)
    else:
        ind = ((sz - 1) // 2,)
    return np.partition(arr, ind, order=field)[list(ind)]

表示3项数组:

In [1123]: mymedian1(la1,'f1')
Out[1123]: 
array([(b'b', 3)], 
      dtype=[('f0', 'S1'), ('f1', '<i4')])

表示6项数组:

In [1124]: la2
Out[1124]: 
array([(b'a', 1), (b'b', 3), (b'c', 5), (b'd', 22), (b'e', 11), (b'f', 3)], 
      dtype=[('f0', 'S1'), ('f1', '<i4')])

In [1125]: mymedian1(la2,'f1')
Out[1125]: 
array([(b'f', 3), (b'c', 5)], 
      dtype=[('f0', 'S1'), ('f1', '<i4')])

使用np.argpartition查看我的早期版本的编辑历史记录。

它甚至适用于第一个字段(字符):

In [1132]: mymedian1(la2,'f0')
Out[1132]: 
array([(b'c', 5), (b'd', 22)], 
      dtype=[('f0', 'S1'), ('f1', '<i4')])