目录
1. 前言
2. numpy.r_
2.1 基本例--输入是1-D的情况
2.2 基本例--输入是2-D的情况
3. 不是函数!
4. 字符选项控制输出
5. Why not just use numpy.concatenate()?
在读代码过程中看到np.r_[...],惊呆了!是不是写错了?一运行还真能运行,还有这样的函数啊(笑哭)。。。
以下简单列举一些搜索到的信息和例子。想要更多更深地了解的小伙伴们自行查看以下连接吧。生命苦短,学海无涯。。。
According to numpy documention[1]:
Translates slice objects to concatenation along the first axis.
This is a simple way to build up arrays quickly. There are two use cases.
将slice对象沿第一轴进行连接。这是创建一个数组的快捷方式,有以下两种使用场景:
If the index expression contains comma separated arrays, then stack them along their first axis.
If the index expression contains slice notation or scalars then create a 1-D array with a range indicated by the slice notation.
简单通俗地来说,就是将一些slice object进行沿第一轴连接(通俗一点的说法是row-wise)连接。但是,row-wise这个说法其实是有点含糊,因为这个预设了矩阵这种形象。因为行和列仅在2维的情况下才有意义。在更广义的多维数组的话语中,已经没有行和列这种概念。所以说‘along the first axis’是严谨而通用的。
例1:
V = np.array([1,2,3,4,5,6 ])
Y = np.array([7,8,9,10,11,12])
print(np.r_[V[0:2],Y[0],V[3],Y[1:3],V[4:],Y[4:]])
输出:[ 1 2 7 4 8 9 5 6 11 12]
其实以上“along the first axis”的说法的效果在输入本身就是1-D的情况下是看不出来的。只要在高维输入的条件下才能看出来。这里举一个2-D的例子来看看。
print('example4...')
a = np.arange(9).reshape(3,3)
b = np.arange(10,19).reshape(3,3)
print(np.r_[a[0:2,1:3], b[0:2,1:3]])
输出:
example4...
[[ 1 2]
[ 4 5]
[11 12]
[14 15]]
从这个输出就可以看出,所谓的‘row-wise concatenation’(对应于2-D情况下的along the first axis)其实是按“列方向”进行连接,稍微有一点反直觉。。。需要注意。
numpy.r_不是函数!不是函数!不是函数!重要的事情说三遍^-^
所以使用它的时候是numpy.r_[...], 而不是numpy.r_(...)
Optional character strings placed as the first element of the index expression can be used to change the output. The strings ‘r’ or ‘c’ result in matrix output. If the result is 1-D and ‘r’ is specified a 1 x N (row) matrix is produced. If the result is 1-D and ‘c’ is specified, then a N x 1 (column) matrix is produced. If the result is 2-D then both provide the same matrix result.
用字符'r'或者'c'可以将1-D数组输出变换为2-D矩阵输出。如果原输出为1-D(其形状为(x,)),则追加'r'控制的话,输出将变为(1, N)的矩阵;追加'c'控制的话,输出将变为(N,1)的矩阵。如下例所示:
V = np.array([1,2,3,4,5,6 ])
Y = np.array([7,8,9,10,11,12])
print(np.r_[V[0:2],Y[0],V[3],Y[1:3],V[4:],Y[4:]])
print(np.r_[V[0:2],Y[0],V[3],Y[1:3],V[4:],Y[4:]].shape)
print(np.r_['r',V[0:2],Y[0],V[3],Y[1:3],V[4:],Y[4:]].shape)
print(np.r_['c',V[0:2],Y[0],V[3],Y[1:3],V[4:],Y[4:]].shape)
输出:
[ 1 2 7 4 8 9 5 6 11 12]
(10,)
(1, 10)
(10, 1)
如果原输出本来就是2-D的,那加不加'r','c'没有影响。
同样还有hstack(), vstack()等等,那为什么要用numpy.r_[]这种怪怪的东西呢?或者说用numpy.r_[]有什么好处呢?
Some people explained in [3], seems reasonable to me.
np.r_
is implemented in the numpy/lib/index_tricks.py
file. This is pure Python code, with no special compiled stuff. So it is not going to be any faster than the equivalent written with concatenate
, arange
and linspace
. It's useful only if the notation fits your way of thinking and your needs.
也就是说,只是一种使得代码更加精简的方式。没有速度或者效率方面的差别。而且,np.r_的底层还是调用np.concatenate().
# example2
a = np.arange(9).reshape(3,3)
b = np.arange(10,19).reshape(3,3)
print(np.concatenate((a[1,1:3], b[1,1:3]), axis = 0))
print(np.r_[a[1,1:3], b[1,1:3]])
如上所示,两者调用大同小异。
唯一的差别(据说是)在于np.concatenate()只接受数组作为输入,而numpy.r_[]接受slice object作为输入。好吧,so what? 我不能分辨其中区别,只不过觉得后者确实更炫一点^-^
类似地还有numpy.c_和numpy.s_...不再赘述。
Reference
[1] numpy.r_ — NumPy v1.21 Manual
[2] python - What does np.r_ do (numpy)? - Stack Overflow
[3] python why use numpy.r_ instead of concatenate - Stack Overflow