是否有任何pythonic方法可以找到数组中特定元组元素的平均值?
我想把这段代码写成pythonic。我的实际数组比这个示例大得多 (5+10+20+3+2)/5 打印(np.平均值(数组,键=λx:x[1])) TypeError:mean()获得意外的关键字参数“key” 如何避免这种情况? 我想用第二个例子 我正在使用Python 3.7,您只需使用:是否有任何pythonic方法可以找到数组中特定元组元素的平均值?,python,arrays,python-3.x,tuples,average,Python,Arrays,Python 3.x,Tuples,Average,我想把这段代码写成pythonic。我的实际数组比这个示例大得多 (5+10+20+3+2)/5 打印(np.平均值(数组,键=λx:x[1])) TypeError:mean()获得意外的关键字参数“key” 如何避免这种情况? 我想用第二个例子 我正在使用Python 3.7,您只需使用: print(sum(tup[1] for tup in array) / len(array)) 或者对于Python 2: print(sum(tup[1] for tup in array) / f
print(sum(tup[1] for tup in array) / len(array))
或者对于Python 2:
print(sum(tup[1] for tup in array) / float(len(array)))
from math import fsum
print(fsum(tup[1] for tup in array) / len(array))
或者对于Python 2来说更简洁一点:
print(sum(tup[1] for tup in array) / float(len(array)))
from math import fsum
print(fsum(tup[1] for tup in array) / len(array))
您可以使用
map
:
np.mean(列表(映射(lambda x:x[1],数组))
使用纯Python:
from operator import itemgetter
acc = 0
count = 0
for value in map(itemgetter(1), array):
acc += value
count += 1
mean = acc / count
如果您的数据不能以列表的形式存储在内存中(因为您说过数据很大),那么迭代方法可能更可取。如果可以,请选择声明式方法:
data = [sub[1] for sub in array]
mean = sum(data) / len(data)
如果您愿意使用numpy
,我会发现这种清洁剂:
a = np.array(array)
mean = a[:, 1].astype(int).mean()
如果您使用的是Python 3.4或更高版本,则可以使用以下模块:
或者,如果您使用的Python版本早于3.4:
average = sum(value[1] for value in array) / len(array)
这些解决方案都使用Python的一个很好的特性,称为生成器表达式。环路
value[1] for value in array
以及时且节省内存的方式创建新序列。看
如果您使用的是Python 2,并且您对整数求和,我们将使用整数除法,它将截断结果,例如:
>>> 25 / 4
6
>>> 25 / float(4)
6.25
为了确保没有整数除法,我们可以将sum
的起始值设置为float
值0.0
。但是,这也意味着我们必须使用括号显式地表示生成器表达式,否则这是一个语法错误,并且不太美观,如注释中所述:
average = sum((value[1] for value in array), 0.0) / len(array)
最好从模块中使用,该模块将返回一个浮点值
:
from math import fsum
average = fsum(value[1] for value in array) / len(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
您可以使用map
代替列表理解
sum(map(lambda x:int(x[1]), array)) / len(array)
或者functools.reduce
(如果您只使用Python2.Xreduce
而不是functools.reduce
)
如果确实要使用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
。在这种情况下,您可以使用float
或int
,这没有什么区别。如果您愿意接受更多类似高尔夫的解决方案,您可以使用vanilla python转换数组,获得一个仅包含数字的列表,然后使用
sum(zip(*array)[1])/len(array)
第一个给出了错误:“int”对象不可调用@evvalKahraman,如果数组的定义如您的问题所示-第一个给出了8.0(在同一版本上测试和验证)。因此,要么您使用的数组在某个地方有不同的值,要么您输入了一个拼写错误x[1]
已经是一个整数了,为什么需要调用int()
?使用lambda比生成器慢30%。但是如果您更喜欢map
,我建议使用操作符.itemgetter(1)
而不是lambda。类似地,functools.reduce
比生成器理解和sum
慢72%。我意识到有更好的方法来编写Python 2代码sum
接受一个参数作为起始值。如果将0.0
传递给它,那么分子将始终是浮点,无需担心。此外,模块中还有一个函数,.我想说float
的转换方式比为sum
@ruohola传递一个奇怪的0.0
值参数更能说明问题。我认为使用fsum
可能最适合Python2。你不能从u future\uuuuu导入部分导入
?@DanielSank是的,这是另一种选择。使用浮点求和的另一个优点是,它可以跟踪部分和,这可以弥补浮点表示中精度的不足。因此,如果我们继续使用fsum
我们根本不需要考虑整数除法,通常也是更好的解决方案。请参阅我关于中的答案。因为它是python 3,所以只需使用。
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