我对Python的设计有疑问。我意识到有些功能是直接在容器类(例如numpy数组)上实现的,而作用于这些容器的其他功能必须从numpy本身调用。一个例子是:
import numpy as np
y = np.array([4,7,9,1])
m1 = np.mean(y) # Ok
m2 = y.mean() # Ok
print(m1 == m2) # True
x = [2,3]
r1 = np.concatenate([x, y]) # Ok
r2 = y.concatenate(x) # AttributeError: 'numpy.ndarray' object has no attribute 'concatenate'
print(r1 == r2)
为什么不能直接从数组中计算均值,而将数组作为没有方法将其连接到另一个方法呢?是否有一个通用规则,哪些函数可以直接在数组上调用而哪些不能?如果两者都有可能,那么用pythonic的方法是什么?
答案 0 :(得分:3)
NumPy history的概述说明了为什么并非所有内容都是一致的:它有两个独立开发的前身。向后兼容要求项目保留array
之类的max
方法。正在进行的开发支持函数语法np.fun(array)
。我想后者的一个原因是它允许array_like
输入(整个NumPy文档中使用的术语):NumPy可以变成ndarray
的任何内容。
答案 1 :(得分:2)
已经讨论了为什么同时存在相同名称的方法和函数的问题,并提供了链接。
但是,请专注于您的两个示例:
mean
仅使用一个数组。从逻辑上讲,它可以是ndarray
方法。
concatenate
接受一个数组列表,并且不优先考虑其中任何一个。
有一个np.append
函数,从表面上看类似于列表.append
方法。但是,只需进行一些修改即可将任务传递到concatenate
上。而且它会导致各种各样的newby错误-与list方法相比,它不是就位,杂乱无章,而且速度较慢。
或者考虑庞大的ufunc
系列。这些是函数,有些采用一个数组,另一些采用两个数组。它们共享通用的ufunc
功能。
np.add(a,b) <=> a+b <=> a.__add__(b)
np.sin(a) # no a.sin()
我怀疑使sin
成为ufunc而不是一种方法的选择受到了通用数学符号的影响。
对我来说,函数方法的一大优点是它可以应用于列表或标量。 np.sin(1)
和np.sin([0,.5,1])
或np.sin(np.arange(0,1,.5))
一样好。
是的,历史在为各种方法的功能混合开辟一段很长的路要走,但是许多选择都是合乎逻辑的。