繁体   English   中英

是否有任何 pythonic 方法来查找数组中特定元组元素的平均值?

[英]Is there any pythonic way to find average of specific tuple elements in array?

我想把这段代码写成 pythonic。 我的真实数组比这个例子大得多。

( 5+10+20+3+2 ) / 5

print(np.mean(array,key=lambda x:x[1])) TypeError: mean() 得到了一个意外的关键字参数 'key'

array = [('a', 5) , ('b', 10), ('c', 20), ('d', 3), ('e', 2)]

sum = 0
for i in range(len(array)):
    sum = sum + array[i][1]

average = sum / len(array)
print(average)

import numpy as np
print(np.mean(array,key=lambda x:x[1]))

如何避免这种情况? 我想用第二个例子。

我正在使用 Python 3.7

如果您使用的是 Python 3.4 或更高版本,则可以使用statistics模块:

from statistics import mean

average = mean(value[1] for value in array)

或者,如果您使用的 Python 版本早于 3.4:

average = sum(value[1] for value in array) / len(array)

这些解决方案都使用了 Python 的一个很好的特性,称为生成器表达式。 循环

value[1] for value in array

及时且高效地创建新序列。 请参阅PEP 289 - 生成器表达式

如果您使用的是 Python 2,并且您正在对整数求和,我们将进行整数除法,这将截断结果,例如:

>>> 25 / 4
6

>>> 25 / float(4)
6.25

为了确保我们没有整数除法,我们可以将sum的起始值设置为float0.0 但是,这也意味着我们必须使用括号显式生成生成器表达式,否则它是一个语法错误,而且不太漂亮,如注释中所述:

average = sum((value[1] for value in array), 0.0) / len(array)

最好使用math模块中的fsum ,它将返回一个float

from math import fsum

average = fsum(value[1] for value in array) / len(array)

如果您确实想使用numpy ,请将其转换为numpy.array并使用numpy索引选择您想要的轴:

import numpy as np

array = np.array([('a', 5) , ('b', 10), ('c', 20), ('d', 3), ('e', 2)])
print(array[:,1].astype(float).mean())
# 8.0

需要转换为数字类型,因为原始数组同时包含字符串和数字,因此属于object类型。 在这种情况下,您可以使用floatint ,这没有区别。

如果您对更多类似高尔夫的解决方案持开放态度,则可以使用 vanilla python 转置数组,获取仅包含数字的列表,然后使用计算平均值

sum(zip(*array)[1])/len(array)

您可以简单地使用:

print(sum(tup[1] for tup in array) / len(array))

或者对于 Python 2:

print(sum(tup[1] for tup in array) / float(len(array)))

或者对于 Python 2 更简洁一点:

from math import fsum

print(fsum(tup[1] for tup in array) / len(array))

使用纯 Python:

from operator import itemgetter

acc = 0
count = 0

for value in map(itemgetter(1), array):
    acc += value
    count += 1

mean = acc / count

如果您的数据不能作为list放入内存(因为您说它很大),则迭代方法可能更可取。 如果可以的话,更喜欢声明式的方法:

data = [sub[1] for sub in array]
mean = sum(data) / len(data)

如果您愿意使用numpy ,我发现这个更干净:

a = np.array(array)

mean = a[:, 1].astype(int).mean()

您可以使用map而不是列表理解

sum(map(lambda x:int(x[1]), array)) / len(array)

functools.reduce (如果你使用 Python2.X 只是reduce而不是functools.reduce

import functools
functools.reduce(lambda acc, y: acc + y[1], array, 0) / len(array)

你可以使用map

np.mean(list(map(lambda x: x[1], array)))

只需使用列表元素的总和和数量找到平均值。

array = [('a', 5) , ('b', 10), ('c', 20), ('d', 3), ('e', 2)]
avg = float(sum(value[1] for value in array)) / float(len(array))
print(avg)
#8.0

这里的问题是你不能直接计算元组列表的平均值作为ndarray因为所有的值都将被转换为str

然而,绕过它的方法是从元组列表中定义结构化数组 ,以便可以将不同的数据类型与元组中的每个元素相关联。

因此,您可以从元组列表中定义结构化数组:

l = [('a', 5) , ('b', 10), ('c', 20), ('d', 3), ('e', 2)]
a = np.array(l, dtype=([('str', '<U1'), ('num', '<i4')]))

然后简单地取数字字段的np.mean ,即元组中的第二个元素:

np.mean(a['num'])
# 8.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM