Python numpy ndarrays让我失望了!我可以回到Matlab吗?
假设我有一个期望ndarray矢量输入的函数。我使用numpy.asarray函数强制输入到我想要的形式,方便的是没有重复已经是ndarrays的东西。但是,如果标量被传入,它有时会变成0d数组而不是1d数组,具体取决于它是如何传入的.0d数组会导致问题,因为我可以索引它。
首先,为什么我不能?说x = np.array(1)
。然后是x.size == 1
,所以它应该有第0个元素。为什么我不能x[0]
或x[-1]
。我知道它希望喜欢一个python int,但它应该在int上进行改进,而不是故意给出相同的限制。
其次,如果numpy asarray函数有一些可选输入来强制输出始终至少为1d数组,那将是非常棒的。然后我可以做x = np.asarray(x, force_at_least_1d=True)
。
然而,我能想出的最佳选择是检查ndim属性,如果它是0,则将其扩展为1.这对我来说感觉不对。我还缺少一些其他的选择吗?
import numpy as np
def func(x, extra_check=True):
r"""Meaningless Example Function for stackoverflow."""
# force input to be ndarrays
x = np.asarray(x)
if x.size == 0:
print('Don''t do anything.')
# Extra test to deal with garbage 0D arrays so that they can be indexed by keep.
# This test is really bothering me. Is there a better way to make it unnecessary?
if extra_check and (x.ndim == 0):
x = x[np.newaxis]
if x[0] > 0 and x[-1] > 5:
print('Do something cool.')
else:
print('Do something less cool.')
if __name__ == '__main__':
# nominally intended use
x1 = np.array([1, 2, 10])
y1 = func(x1) # prints "Do something cool."
# single item use
x2 = x1[x1 == 2]
y2 = func(x2) # prints "Do something less cool."
# scalar single item use that works with extra check
x3 = x1[1]
y3 = func(x3) # prints "Do something less cool."
# scalar single item that will fail without extra check
x4 = x1[1]
y4 = func(x4, extra_check=False) # raises IndexError
所以我的主要问题是,是否有比我更好的方式。如果没有,其他人是否同意应该有?我对Python比较陌生,所以我从来没有尝试过为源代码贡献任何东西,但我想我可以寻找另一个问题来解释这个过程。
如果重要的话,我在python v3.5.1和numpy 1.9.3上。谢谢!
答案 0 :(得分:13)
其次,如果numpy asarray函数有一些可选输入来强制输出始终至少为1d数组,那将是非常棒的。然后我可以做类似x = np.asarray(x,force_at_least_1d = True)的事情。
np.asarray
没有,但np.array
确实 - ndmin
- 还有专门的np.atleast_1d
功能(也是2和3):
>>> np.array(0, ndmin=1)
array([0])
>>> np.atleast_1d(np.array(0))
array([0])
答案 1 :(得分:2)
任何数组都可以使用带有x.ndim
元素的元组进行索引
2D:
In [238]: x=np.array([[1]])
In [239]: x.ndim
Out[239]: 2
In [240]: x[(0,0)] # same as x[0,0]
Out[240]: 1
1D:
In [241]: x=np.array([1])
In [242]: x[(0,)] # (0,) to distinguish from (0)==0
Out[242]: 1
0D:
In [243]: x=np.array(1)
In [244]: x[()] # empty tuple
Out[244]: 1
索引元素实际上不会返回标量
In [250]: x=np.array([[1]])
In [251]: type(x[0,0])
Out[251]: numpy.int32
In [252]: x[0,0][()]
Out[252]: array(1)
它返回一个dtype
对象,它接受0d索引。
你提到MATLAB。 - 一切都是2d(或更高);将0d设置为下限是不是更合乎逻辑? :)
另一个答案提到ndmin
参数,以及atleast_1d
(还有2d和3d)。查看atleast_1d
的文档和代码,了解它如何重塑各种案例。 e.g。
if len(ary.shape) == 0 :
result = ary.reshape(1)