在numpy
中,生成的数组的维度在运行时会有所不同。
1d数组和具有1列的2d数组之间经常存在混淆。
在一种情况下,我可以迭代列,在另一种情况下,我不能。
你如何优雅地解决这个问题?
为了避免在检查维度的if
语句中乱丢我的代码,我使用了这个函数:
def reshape_to_vect(ar):
if len(ar.shape) == 1:
return ar.reshape(ar.shape[0],1)
return ar
但是,这种感觉不够优雅且成本高昂。有更好的解决方案吗?
答案 0 :(得分:14)
最简单的方法:
ar.reshape(-1, 1)
答案 1 :(得分:8)
你可以做 -
ar.reshape(ar.shape[0],-1)
reshape
的第二个输入:-1
负责第二个轴的元素数量。因此,对于2D
输入案例,它不会发生任何变化。对于1D
输入大小写,它会创建一个2D
数组,其中所有元素都被“推送”到第一个轴,因为ar.shape[0]
是元素的总数。
示例运行
1D案例:
In [87]: ar
Out[87]: array([ 0.80203158, 0.25762844, 0.67039516, 0.31021513, 0.80701097])
In [88]: ar.reshape(ar.shape[0],-1)
Out[88]:
array([[ 0.80203158],
[ 0.25762844],
[ 0.67039516],
[ 0.31021513],
[ 0.80701097]])
2D案例:
In [82]: ar
Out[82]:
array([[ 0.37684126, 0.16973899, 0.82157815, 0.38958523],
[ 0.39728524, 0.03952238, 0.04153052, 0.82009233],
[ 0.38748174, 0.51377738, 0.40365096, 0.74823535]])
In [83]: ar.reshape(ar.shape[0],-1)
Out[83]:
array([[ 0.37684126, 0.16973899, 0.82157815, 0.38958523],
[ 0.39728524, 0.03952238, 0.04153052, 0.82009233],
[ 0.38748174, 0.51377738, 0.40365096, 0.74823535]])
答案 2 :(得分:3)
divakar的答案变体是:x = np.reshape(x, (len(x),-1))
,它还处理输入为1d或2d列表的情况。
答案 3 :(得分:0)
我问过dtype
,因为你的例子令人费解。
我可以制作一个包含3个元素(1d)和3个字段的结构化数组:
In [1]: A = np.ones((3,), dtype='i,i,i')
In [2]: A
Out[2]:
array([(1, 1, 1), (1, 1, 1), (1, 1, 1)],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
我可以按名称访问一个字段(添加括号不会更改内容)
In [3]: A['f0'].shape
Out[3]: (3,)
但如果我访问2个字段,我仍然会得到1d数组
In [4]: A[['f0','f1']].shape
Out[4]: (3,)
In [5]: A[['f0','f1']]
Out[5]:
array([(1, 1), (1, 1), (1, 1)],
dtype=[('f0', '<i4'), ('f1', '<i4')])
实际上,如果我查看值
,那些额外的括号就很重要In [22]: A['f0']
Out[22]: array([1, 1, 1], dtype=int32)
In [23]: A[['f0']]
Out[23]:
array([(1,), (1,), (1,)],
dtype=[('f0', '<i4')])
如果阵列是一个简单的2d阵列,我仍然没有得到你的形状
In [24]: A=np.ones((3,3),int)
In [25]: A[0].shape
Out[25]: (3,)
In [26]: A[[0]].shape
Out[26]: (1, 3)
In [27]: A[[0,1]].shape
Out[27]: (2, 3)
但是关于确保数组是2d的问题,无论索引返回1d还是2,你的函数基本上都没问题
def reshape_to_vect(ar):
if len(ar.shape) == 1:
return ar.reshape(ar.shape[0],1)
return ar
您可以测试ar.ndim
而不是len(ar.shape)
。但无论哪种方式,它都不昂贵 - 也就是说,执行时间很短 - 没有大阵列操作。 reshape
不会复制数据(除非您的步幅很奇怪),因此只需使用共享数据指针创建新数组对象的成本。
查看np.atleast_2d
的代码;它测试0d和1d。在第一种情况下,它返回result = ary[newaxis,:]
。它首先添加额外的轴,添加轴的自然numpy
位置。你最后添加它。
ar.reshape(ar.shape[0],-1)
是一种绕过if
测试的聪明方法。在小时序测试中它更快,但我们谈论的是微秒,即函数调用层的效果。
np.column_stack
是另一个根据需要创建列数组的函数。它使用:
if arr.ndim < 2:
arr = array(arr, copy=False, subok=True, ndmin=2).T
答案 4 :(得分:0)
为了避免首先需要重新整形,如果使用列表或“运行”切片切片行/列,您将得到一个包含一行/列的二维数组
import numpy as np
x = np.array(np.random.normal(size=(4,4)))
print x, '\n'
Result:
[[ 0.01360395 1.12130368 0.95429414 0.56827029]
[-0.66592215 1.04852182 0.20588886 0.37623406]
[ 0.9440652 0.69157556 0.8252977 -0.53993904]
[ 0.6437994 0.32704783 0.52523173 0.8320762 ]]
y = x[:,[0]]
print y, 'col vector \n'
Result:
[[ 0.01360395]
[-0.66592215]
[ 0.9440652 ]
[ 0.6437994 ]] col vector
y = x[[0],:]
print y, 'row vector \n'
Result:
[[ 0.01360395 1.12130368 0.95429414 0.56827029]] row vector
# Slice with "running" index on a column
y = x[:,0:1]
print y, '\n'
Result:
[[ 0.01360395]
[-0.66592215]
[ 0.9440652 ]
[ 0.6437994 ]]
相反,如果您使用单个数字来选择行/列,则会产生一维数组,这是导致问题的根本原因:
y = x[:,0]
print y, '\n'
Result:
[ 0.01360395 -0.66592215 0.9440652 0.6437994 ]
答案 5 :(得分:0)
# all element should be same data type (e.g. box)
store = []
def get_valid_object():
if has_value:
return that_object_with_value
else: # not needed but for the clarification
# None is not the same data type here (e.g. box)
return None
# use
box = get_valid_object()
if box:
store += box
答案 6 :(得分:0)
从一维数组(N)到二维数组主要有两种方法
1列数组
(N x 1):
np.newaxis
编制索引; reshape()
方法重塑。x = np.array([1, 2, 3]) # shape: (3,) <- 1d
x[:, None] # shape: (3, 1) <- 2d (single column matrix)
x[:, np.newaxis] # shape: (3, 1) <- a meaningful alias to None
x.reshape(-1, 1) # shape: (3, 1)