Summary: this is the introduction and summary of numpy array/matrix manipulation. Some are with very detailed explaination which I think is more detailed than the numpy document.
import numpy as np
x = np.arange(24).reshape(2, 3, 4)
print np.ravel(x, order = "C")
1. 2. np.ndarray.flatten¶
np.ndarray.flatten(order = )
把一个矩阵(matrix,或者叫数组array)转为一个向量。order:
是展开的顺序,'C'
-- 按行,'F'
-- 按列,'A'
-- 原顺序,'k'
-- 元素在内存中的出现顺序。
x = np.arange(24).reshape(2, 3, 4)
print x.flatten(order = "C")
print x.flatten(order = "F")
print x.flatten(order = "A")
print x.flatten(order = "k")
1.3. np.flat
¶
np.flat
返回一个矩阵拉直以后的迭代器(iterator
)
x = np.arange(1, 7).reshape(2, 3)
x.flat[:]
2. 翻转操作¶
function | 描述 | |
---|---|---|
1. | transpose |
矩阵转置,行变列,列变行 |
2. | rollaxis |
矩阵沿着给定的轴滚动,直到指定位置 |
3. | swapaxes |
交换轴 |
2.1. np.transpose
or array.T
¶
np.transpose
or array.T
用来对矩阵进行行和列的转置。
x = np.arange(1, 7).reshape(2, 3)
print "\n 原始矩阵为: \n"
print x
print "\n 转置后的矩阵为: \n"
print np.transpose(x)
2.2. np.rollaxis¶
np.rollaxis(a, axis = , start = )有三个参数,第一个参数a
是要进行运算的矩阵,第二个参数axis
是要被移动的轴,第三个参数start
是把第二个参数放到哪儿。根据函数的说明文档,是把第二个参数放到第三个参数之前。
比如说,假如矩阵a
的维度为(2, 3, 4)
, np.rollaxis(a, 0, 3)
是把第一个轴(0轴,因为index = 0)放到index = 3之前,也就是index = 2的位置,即把(2, 3, 4)
的2
调到最后,所以输出矩阵就应该是(3, 4, 2)
。
相应的np.rollaxis(a, 0, 0)
和np.rollaxis(a, 0, 1)
都是一样的结果,因为都是把0轴调到第一个位置,所以应该就是a
本身.
np.rollaxis(a, 1, 3)
就是把第二个轴(1轴)调到2轴(index = 3之前的轴,所以是index = 2轴,即第三轴).所以输出应该是(2, 4, 3)
x = np.arange(24).reshape(2, 3, 4)
print '把0轴放到0轴之前,所以还是原来的矩阵x: ' + str(np.rollaxis(x, 0, 0).shape)
print '把0轴放到1轴之前,还是0轴,所以还是原来的矩阵x: ' + str(np.rollaxis(x, 0, 1).shape)
print '把0轴放到2轴之前,所以2和3交换位置: ' + str(np.rollaxis(x, 0, 2).shape)
print '把0轴放到3轴之前,所以2到了最后: ' + str(np.rollaxis(x, 0, 3).shape)
print '把1轴放到3轴之前,所以3到了最后: ' + str(np.rollaxis(x, 1, 3).shape)
2.3. np.swapaxes¶
np.swapaxes
比较直观,就是把两个轴对换一下
x = np.arange(24).reshape(2, 3, 4)
print np.swapaxes(x, 1, 2).shape
3. 元素重排¶
function | 描述 | |
---|---|---|
1. | flip fliplr flipud |
对矩阵进行翻转 |
2. | roll |
对矩阵的元素进行滚动位移 |
3. | rot90 |
旋转矩阵 |
3.1. np.flip np.fliplr np.flipud
¶
np.flip(array, axis), np.fliplr(array), np.flipud(array)
均是对矩阵进行翻转操作。
np.flip(array, axis = 0) == np.flipud(array) == array[::-1,...]
np.flip(array, axis = 1) == np.fliplr(array) == array[:,::-1]
x = np.arange(8).reshape((2, 2, 2))
print "原始矩阵为: \n"
print x
print "\n 1. 进行axis=0上的翻转:x[0, :, :]和x[1, :, :]调换位置: \n"
print np.flipud(x)
print np.all(np.flipud(x) == x[::-1,...])
print "\n 2. 进行axis=1上的翻转: x[:, 0, :]和x[:, 1, :]调换位置: \n"
print np.fliplr(x)
print np.all(np.fliplr(x) == x[:,::-1])
3.2. np.roll
¶
np.roll(array, shift, axis)
滚动移位: 移动矩阵元素的位置,或者行/列整体移动
x = np.arange(16).reshape(4, 4)
print "\n 1. 没有axis则进行元素移位,把最后2个元素移到第一个第二个位置 \n"
print np.roll(x, 2)
print "\n 2. axis = 0, 把最后两行整体移到第一行第二行"
print np.roll(x, 2, axis = 0)
print "\n 3. axis = 1, 把最后1列整体移到第一列"
print np.roll(x, 1, axis = 1)
3.3. np.rot90
¶
np.rot90(array, k)
对矩阵整体进行k
次的90度转置.
x = np.arange(6).reshape(2, 3)
print "\n 1. 旋转90度 \n"
print np.rot90(x, 1)
print "\n 2. 再旋转90度 \n"
print np.rot90(x, 2)
print "\n 3. 旋转4个90度,变成了自己 \n"
print np.rot90(x, 4)
x = np.array([[1], [2], [3]]) # shape = (3, 1)
y = np.array([4, 5, 6]) # shape = (, 3)
# 对 y 广播 x
b = np.broadcast(x,y)
print b.shape
for (i, j) in b:
print i, j
b = np.broadcast(x,y)
c = np.empty(b.shape)
c.flat = [i * j for (i, j) in b]
print c
print x * y
4.2. np.broadcast_to
¶
np.broadcast_to
将原始数组广播到给定的新的shape.下面的例子中把shape为(2, 4)的矩阵在0轴上广播了三次.
x = np.arange(8).reshape(2, 4)
print np.broadcast_to(x, (3, 2, 4))
4.3. np.expand_dims¶
np.expand_dims(arr, axis)
在原始矩阵上增加一个维度,所以在那个维度上的dim=1,相当于把原来的矩阵整体打包放到新的维度里面了。
x = np.arange(4).reshape(2, 2)
print "原始矩阵的shape: " + str(x.shape) + '\n'
print "在index=0的方向增加一个维度: " + str(np.expand_dims(x, axis = 0).shape) + '\n'
print "np.expand_dims(x, axis = 1) 在index=1增加一个维度,所以现在维度为(2, 1, 2) \n"
np.expand_dims(x, axis = 1)
4.4. np.squeeze¶
np.squeeze(arr, axis)
把矩阵dim=1的那个维度或者那些维度去掉
print "\n 1. 输入矩阵维度为(1, 2, 2),squeeze后维度为(2, 2) \n"
x = np.arange(4).reshape(1, 2, 2)
print x.shape
print np.squeeze(x).shape
print "\n 2. 输入矩阵维度为(1, 1, 4),squeeze后维度为(4, ) \n"
x = np.arange(4).reshape(1, 1, 4)
print x.shape
print np.squeeze(x).shape
x = np.arange(12).reshape(3, 4)
y = np.arange(12).reshape(3, 4)
print np.concatenate((x, y), axis = 0).shape
print np.concatenate((x, y), axis = 1).shape
5.2. np.stack
¶
np.stack(arrays, axis)
沿着新轴连接数组,产生多一个轴的数组
下面输入的两个数组shape相同,shape为(3, 4)
np.stack((x, y), axis = 0)
沿着axis=0
连接两个矩阵,所以产生的新矩阵在axis = 0
上维度为2;新的矩阵shape为(2L, 3L, 4L)
np.stack((x, y), axis = 1)
沿着axis=1
连接两个矩阵,所以产生的新矩阵在axis = 1
上维度为2;新的矩阵shape为(3L, 2L, 4L)
x = np.arange(12).reshape(3, 4)
y = np.arange(12).reshape(3, 4)
print np.stack((x, y), axis = 0).shape
print np.stack((x, y), axis = 1).shape
5.3. np.vstack
¶
np.vstack((a1, a2, ...))
用来竖直连接输入的数组,跟np.r_[]
很像。也可以用np.concatenate((a1, a2, ...), axis = 0)
来得到。
print np.vstack((x, y))
print "\n this is the same as np.r_[x, y]: \n"
print np.r_[x, y]
5.4. np.hstack
¶
np.hstack((a1, a2, ...))
用来水平连接输入的数组,跟np.c_[]
很像。也可以用np.concatenate((a1, a2, ...), axis = 1)
来得到。
print np.hstack((x, y))
print "\n this is the same as np.c_[x, y]: \n"
print np.c_[x, y]
np.r_[x.flatten(), [99, 999]]
print x.flatten().shape
np.c_[x.flatten(), np.repeat(99, 12)]
x = np.arange(12).reshape(3, 4)
res = np.split(x, 2, axis = 1)
print res
6.2. np.hsplit
¶
np.hsplit = np.split( , , axis = 1)
. np.hsplit(array, k)
的k
必须能被array.shape[1]
整除
np.hsplit(x, 2)
6.3. np.hsplit
¶
np.hsplit = np.split( , , axis = 0)
np.vsplit(x, 3)
x = np.arange(12).reshape(3, 4)
print "1. 从(3, 4)resize为(2, 6),这个等价于 `x.reshape(2, 6)`. (3, 4)和(2, 6)的元素个数相等: \n"
print np.resize(x, (2, 6))
print "\n "
print "2. 从(3, 4)resize为(3, 6), 元素变多,所以原始矩阵的前六个元素被重复使用了: \n"
print np.resize(x, (3, 6))
7.2. np.append
¶
np.append(array, values, axis)
向数组添加元素。如果不带axis
参数,那么array
和values
会先被拉平成向量然后再append。
x = np.arange(8).reshape(2, 4)
print "\n 1. 没有axis参数,被拉直成向量 \n"
print np.append(x, [1, 2, 3, 4])
print "\n 2. 沿着0轴append新的值 \n"
print np.append(x, [[1, 2, 3, 4]], axis = 0)
print "\n 3. 沿着1轴append新的值 \n"
print np.append(x, [[1], [2]], axis = 1)
. np.insert
¶
np.insert(array, obj, values, axis)
在给定的索引(obj)之前,沿着给定的轴(axis)在输入的数组(arr)中插入值(values). 如同np.append
,如果没有axis
,那么输入的数组会被展开。
x = np.arange(12).reshape(3, 4)
print "\n 1. np.insert(x, 3, [99, 999]): \
\n在index=3之前插入[99, 999], 因为没有axis,所以被展开成向量 \n"
print np.insert(x, 3, [99, 999])
print "\n 2. np.insert(x, 2, [[99, 999, 9999, 99999]], axis = 0): \
\n axis=0,插入新的一行,注意插入的行向量shape是(1, 4) \n"
print np.insert(x, 2, [[99, 999, 9999, 99999]], axis = 0)
print "\n 3. np.insert(x, 3, [99, 999, 9999], axis = 1): \
\n axis=1, 插入新的一列,注意插入的列向量shape是(3, ) \n"
print np.insert(x, 3, [99, 999, 9999], axis = 1)
print "\n 4. np.insert(x, 3, [[99], [999], [9999]], axis = 1): \
\n 如果插入一个shape为(3, 1)的向量,会自动把插入的向量补齐为(3, 3) \n"
print np.insert(x, 3, [[99], [999], [9999]], axis = 1)
print "\n 5. np.insert(x, 3, [9999], axis = 1): \n直接插入一个值的向量,自动补齐 \n"
print np.insert(x, 3, [9999], axis = 1)
numpy.delete
¶
numpy.delete(array, obj, axis)
返回从输入数组中沿着指定的轴删除去子数组以后的新数组。
x = np.arange(12).reshape(3, 4)
print "\n 1. np.delete(x, 3): 删除index=3的值(值为3), 因为没有axis,所以被展开成向量 \n"
print np.delete(x, 3)
print "\n 2. np.delete(x, 2, axis = 1): 删除index=2(value = 2)的列向量(axis = 1) \n"
print np.delete(x, 2, axis = 1)
print "\n 3. np.delete(x, np.s_[::2]): 展开成向量,然后每隔1个删除一个值 \n"
print np.delete(x, np.s_[::2])
numpy.unique
¶
numpy.unique(array, return_index, return_inverse, return_counts)
的输入为一个矩阵,return_index = True
返回原始输入数组产生去重数组的下标;return_inverse = True
返回去重数组在原始数组的下标,返回值跟原始输入数组shape相同,可以用来重构原始数组;return_counts = True
返回去重数组在原始数组中出现的频率
np.random.seed(0)
x = np.random.poisson(lam = 3, size = 10)
print x
print "\n 1. 返回唯一值 \n"
print np.unique(x)
print "\n 2. 返回唯一值,和原始数组产生唯一值向量的下标\n"
print np.unique(x, return_index = True)
print "\n 3. 返回唯一值,和原始数组的下标,可以用来重构原始数组 \n"
print np.unique(x, return_inverse = True)
print "\n 4. 返回唯一值,和原始数组的下标,可以用来重构原始数组,重构: \n"
u, v = np.unique(x, return_inverse = True)
print u[v]
print "\n 5. 返回唯一值的频率 \n"
print np.unique(x, return_counts = True)