numpy数组的形状(shape)和长度(len)的区别

19

比较shapelen有什么区别(例如性能)?考虑下面的例子:

In [1]: import numpy as np

In [2]: a = np.array([1,2,3,4])

In [3]: a.shape
Out[3]: (4,)

In [4]: len(a)
Out[4]: 4

快速运行时比较表明没有区别:

In [17]: a = np.random.randint(0,10000, size=1000000)

In [18]: %time a.shape
CPU times: user 6 µs, sys: 2 µs, total: 8 µs
Wall time: 13.1 µs
Out[18]: (1000000,)

In [19]: %time len(a)
CPU times: user 5 µs, sys: 1 µs, total: 6 µs
Wall time: 9.06 µs
Out[19]: 1000000

那么,区别在哪里?哪个更符合Python风格呢?(我猜是使用shape)。

5个回答

21

我不认为在这里需要担心性能——任何差异都应该非常微小。

我认为更符合Python风格的选择可能是更符合你的需求:

a.shape 可能包含比 len(a) 更多的信息,因为它包含了所有轴向上的大小,而 len 只返回第一个轴向上的大小:

>>> a = np.array([[1,2,3,4], [1,2,3,4]])
>>> len(a)
2
>>> a.shape
(2L, 4L)

如果您只使用一维数组,那么我个人更喜欢在需要数组大小时使用len(a)


22
完整性起见:a.shape[0] == len(a) - Imanol Luengo
1
为了完整起见,a.size也是一个选项。尽管个人更喜欢len(a),以防万一a不是numpy数组,在你不小心的时候有时会发生这种情况。 - Mong H. Ng

10

从源代码来看,shape 基本上使用了 len()https://github.com/pandas-dev/pandas/blob/master/pandas/core/frame.py

@property
def shape(self) -> Tuple[int, int]:
    return len(self.index), len(self.columns)

def __len__(self) -> int:
    return len(self.index)

调用shape将尝试运行两个维度计算。因此,df.shape[0] + df.shape[1]可能比len(df.index) + len(df.columns)慢。尽管如此,在性能方面,除了一个巨大的2D dataframe之外,差异应该可以忽略不计。
因此,与之前的答案一致,如果您需要两个维度,请使用df.shape,对于单个维度,从概念上讲,len()更合适。
查看property vs method答案,所有的指向都是代码的可用性和可读性。因此,再次强调,在您的情况下,如果您想要有关整个数据框的信息,只是为了检查或者例如将形状元组传递给函数,请使用shape。对于单列,包括索引(即df的行),请使用len()

1

其实有微小的差异。如果您处理时间序列数据并知道数据是向量(1D),请使用len,因为它更快,并养成习惯,即使只是非常微小的差异。 Bish的回答已经解释了幕后发生了什么。

使用%%timeit进行适当的基准测试(我测试了几次),结果显示len胜出:

# tested on pandas DataFrame

%%timeit
len(yhat.values)
# 576 ns ± 1.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%%timeit
yhat.values.shape[0]
# 607 ns ± 1.07 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

此外,在 1D 中,len 作为长度比 .shape[0] 更具信息性(在阅读代码时) 。

1
得到了非常相似的结果,len()函数稍微更快。https://twitter.com/pfedprog/status/1499894398032744450?s=20&t=tOd_np7pKpB4rFt8tN85Ow - Pavel Fedotov

0

对于一维情况,len和shape将产生相同的结果。 对于其他情况,shape会提供更多信息。这取决于程序在哪个方面提供更好的性能。我建议您不要过于担心性能。


1
尝试:len(np.array([0,2])),type(np.array([0,2]).shape)len 返回一个整数,shape 返回一个整数元组。如果实际在代码中使用结果而不是通过视觉检查,则这很重要。 - Mark_Anderson

0
import numpy as np

x = np.linspace(1, 10, 10).reshape((5, 2))
print(x)
print(x.size)
print(len(x))

会输出以下内容:

[[ 1.  2.]
 [ 3.  4.]
 [ 5.  6.]
 [ 7.  8.]
 [ 9. 10.]]
10
5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接