Python使用Numpy变换数组形状

一、 修改数组的形状

1、重塑数组形状

方法 作用
reshape() 不修改原数组的形状,返回一个视图,会影响原数组的数据
resize() 直接作用于原数组
shape() 直接作用于原数组

若不理解视图,可以通过 视图与拷贝 这篇博客进行了解。

  • ndarry.reshape()
1
2
3
4
5
6
ndarry.reshape(shape)
shape:填入生成的数组形状(元组)

特点:
1、有返回值,返回一个视图
2、不直接作用于原数组(不改变原数组的形状),但影响原数组的元素

代码:

1
2
3
4
5
6
7
import numpy as np
n1 = np.array([[2,4,3,2],[8,4,2,9],[8,3,4,9]])
# 形状
n1.shape
# (3, 4)
# reshape
n1.reshape((4,3))
  • ndarry.resize()
1
2
3
4
5
6
7
resize(shape) :谨慎使用!

shape:填入生成的数组形状(元组)

特点:
1、无返回值
2、直接作用于原数组(改变原数组的形状)

代码

1
2
3
4
5
6
n1 = np.array([[2,4,3,2],[8,4,2,9],[8,3,4,9]])
n1.resize(2,2,3)

# n1形状已修改
n1.shape
# (2, 2, 3)
  • ndarry.shape
1
2
shape
通过属性直接赋值修改(改变原数组的形状)

代码

1
2
3
4
5
6
n1 = np.array([[2,4,3,2],[8,4,2,9],[8,3,4,9]])
# 数组的原始形状
n1.shape
# (4, 3)
n1.shape = (2,6)
n1

2、多维数换向一维数组转换

  • ndarry.ravel()
1
2
3
4
5
6
7
ndarry.ravel(order=)

当不设置参数order,默认将数组横向展平为一维数组
当设置参数order = 'F',即为将数组纵向展平为一维数组

注意:
使用ravel函数修改形状,得到一个视图,不会改变原数组的形状,但会会改变原数组中的元素!

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
n1
# array([[2, 4, 3],
# [2, 8, 4],
# [2, 9, 8],
# [3, 4, 9]])
# 横向展平为一维数组
n1.ravel()
# array([2, 4, 3, 2, 8, 4, 2, 9, 8, 3, 4, 9])
# 纵向展平为一维数组
n1.ravel(order='F')
# array([2, 2, 2, 3, 4, 8, 9, 4, 3, 4, 8, 9])
# 原数组形状未改变
n1
# array([[2, 4, 3],
# [2, 8, 4],
# [2, 9, 8],
# [3, 4, 9]])
# 修改元素
n1.ravel()[3] = 77
# 原数组数据被修改
n1
# array([[ 2, 4, 3],
# [77, 8, 4],
# [ 2, 9, 8],
# [ 3, 4, 9]])
  • ndarry.flatten()
1
2
3
4
5
6
7
8
ndarry.flatten(order=)

当不设置参数order,默认为将数组横向展平为一维数组
当设置参数order = 'F',则将数组纵向展平为一维数组

注意:
使用flatten函数不会对原数组产生任何影响
(原数组形状和元素都不受其影响)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
n1
# array([[ 2, 4, 3],
# [77, 8, 4],
# [ 2, 9, 8],
# [ 3, 4, 9]])
# # 将数组横向展平成一维数组
n1.flatten()
# array([ 2, 4, 3, 77, 8, 4, 2, 9, 8, 3, 4, 9])
# 展平时候的形状
n1.flatten().shape
# (12,)
# 将数组纵向展平成一维数组
n1.flatten(order='F')
# array([ 2, 77, 2, 3, 4, 8, 9, 4, 3, 4, 8, 9])
# flatten修改元素数值
n1.flatten()[1] = 6
# 不影响原数组的形状和元素数据
n1
# array([[ 2, 4, 3],
# [77, 8, 4],
# [ 2, 9, 8],
# [ 3, 4, 9]])
  • ndarry.reshape(-1)

函数说明

1
2
3
4
5
6
7
8
9
10
11
12
n1.reshape(-1)
-1:表示自动计算

n1.reshape(m,-1)
指定行为m,列自动计算

n1.reshape(-1,n)
指定列为n,行自动计算

注意:
1、不影响原数组的形状
2、影响原数组的元素

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
n1
# array([[ 2, 4, 3],
# [77, 8, 4],
# [ 2, 9, 8],
# [ 3, 4, 9]])
# 横向展平
n1.reshape(-1)
# array([ 2, 4, 3, 77, 8, 4, 2, 9, 8, 3, 4, 9])
# 同n1.reshape(-1) 数组只有一个维度,自动计算长度
n1.reshape(-1,)
# array([ 2, 4, 3, 77, 8, 4, 2, 9, 8, 3, 4, 9])
# 指定列数,自动计算行数
n1.reshape(-1,6)
# array([[ 2, 4, 3, 77, 8, 4],
# [ 2, 9, 8, 3, 4, 9]])
# 指定行数
n1.reshape(3,-1)
# array([[ 2, 4, 3, 77],
# [ 8, 4, 2, 9],
# [ 8, 3, 4, 9]])
# 不改变原数组的形状
n1
# array([[ 2, 4, 3],
# [77, 8, 4],
# [ 2, 9, 8],
# [ 3, 4, 9]])
# 通过reshape修改元素,原数组元素数据产生变化
n1.reshape(-1,)[0] = 12
n1
# array([[12, 4, 3],
# [77, 8, 4],
# [ 2, 9, 8],
# [ 3, 4, 9]])

3、 增加一个维度

  • np.newaxis() 所在位置增加一个维度

一维扩展为二维

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 一维度数组
n2 = np.arange(10)
n2
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
n2.shape
# (10,)
# 行方向增加一个维度
n2[np.newaxis,:]
# array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
n2[np.newaxis,:].shape
# (1, 10)
# 列方向增加一个维度
n2[:,np.newaxis]
# array([[0],
# [1],
# [2],
# [3],
# [4],
# [5],
# [6],
# [7],
# [8],
# [9]])

n2[:,].shape
# (10, 1)

二维扩展为三维

1
2
3
4
5
6
7
8
9
# 二维度数组
n2 = np.arange(10).reshape(2,5)
n2.shape
# (2, 5)
n2[np.newaxis,:,:]
# array([[[0, 1, 2, 3, 4],
# [5, 6, 7, 8, 9]]])
n2[np.newaxis,:,:].shape
# (1, 2, 5)

以此类推,将小维度数组扩展成更多维的数组。

4、数组行列转置

  • ndarray.T 属性
1
2
3
4
5
6
7
8
9
10
n2
# array([[0, 1, 2, 3, 4],
# [5, 6, 7, 8, 9]])
# ndarray.T 将数据按照对角线进行行列倒置,行变成了列,列变成了行
n2.T
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])
  • ndarray.transpose()
1
2
3
4
5
6
7
# 同ndarray.T 
n2.transpose()
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])
  • ndarray.swapaxes(1,0)
1
2
3
4
5
6
7
# 必须填入两个参数,进行行列转换
n2.swapaxes(1,0)
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])

二、数据的拼接(合并)

  • np.hstack() 水平拼接
1
2
3
4
np.hstack(tup) 数组的水平拼接
水平拼接即为横向拼接,数组的行数要一致

tup:ndarray序列

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 准备数组1
a1 = np.array([[3,4,5],[2,4,1],[8,9,4]])
a1
# array([[3, 4, 5],
# [2, 4, 1],
# [8, 9, 4]])
# 准备数组2
a2 = np.array([[7,3,1,5],[3,9,4,1],[2,8,7,4]])
a2
# array([[7, 3, 1, 5],
# [3, 9, 4, 1],
# [2, 8, 7, 4]])
# 进行水平拼接
np.hstack([a1,a2])
# array([[3, 4, 5, 7, 3, 1, 5],
# [2, 4, 1, 3, 9, 4, 1],
# [8, 9, 4, 2, 8, 7, 4]])
  • np.vstack() 竖直拼接
1
2
3
4
np.vstack(tup) 数组的水平拼接
竖直拼接即为纵向拼接,数组的列数要一致

tup:ndarray序列

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 准备数组1
a2 = np.array([[7,3,1,5],[3,9,4,1],[2,8,7,4]])
a2
# array([[7, 3, 1, 5],
# [3, 9, 4, 1],
# [2, 8, 7, 4]])
# 准备数组2
a3=np.arange(12).reshape(3,4)
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
# 进行竖直拼接
np.vstack((a3,a2))
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [ 7, 3, 1, 5],
# [ 3, 9, 4, 1],
# [ 2, 8, 7, 4]])
  • np.concatenate() 指定数组的拼接方向
1
2
3
4
np.concatenate((a1, a2, ...), axis=0, out=None)

axis = 0 :按照行的方向进行拼接,竖直拼接
axis = 1 :按照列的方向进行拼接,横向拼接

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 准备数组1
a1 = np.array([[3,4,5],[2,4,1],[8,9,4]])
a1
# array([[3, 4, 5],
# [2, 4, 1],
# [8, 9, 4]])
# 准备数组2
a2 = np.array([[7,3,1,5],[3,9,4,1],[2,8,7,4]])
a2
# array([[7, 3, 1, 5],
# [3, 9, 4, 1],
# [2, 8, 7, 4]])
# 按照列的方向进行拼接,横向拼接
np.concatenate((a1,a2),axis = 1)
# array([[3, 4, 5, 7, 3, 1, 5],
# [2, 4, 1, 3, 9, 4, 1],
# [8, 9, 4, 2, 8, 7, 4]])
# 准备数组3
a3=np.arange(12).reshape(3,4)
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
# 按照行的方向进行拼接,竖直拼接
np.concatenate((a3,a2),axis = 0)
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [ 7, 3, 1, 5],
# [ 3, 9, 4, 1],
# [ 2, 8, 7, 4]])

三、 数据的复制

  • np.tile(ndarry,(m,n)) 指定数组的方向复制
1
2
3
4
np.tile(ndarry,(m,n))
tile是瓷砖的意思,顾名思义,这个函数就是把数组像瓷砖一样铺展开来。
m:表示按照行的方向进行复制,铺展m次
m:表示按照列的方向进行复制,铺展n次

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
a2
# array([[7, 3, 1, 5],
# [3, 9, 4, 1],
# [2, 8, 7, 4]])

# 按照行的方向进行复制,铺展3次,竖直铺展
np.tile(a2,(3,1))
# array([[7, 3, 1, 5],
# [3, 9, 4, 1],
# [2, 8, 7, 4],
# [7, 3, 1, 5],
# [3, 9, 4, 1],
# [2, 8, 7, 4],
# [7, 3, 1, 5],
# [3, 9, 4, 1],
# [2, 8, 7, 4]])
# 按照列的方向进行复制,铺展2次,横向铺展
np.tile(a2,(1,2))
# array([[7, 3, 1, 5, 7, 3, 1, 5],
# [3, 9, 4, 1, 3, 9, 4, 1],
# [2, 8, 7, 4, 2, 8, 7, 4]])
# 分别按照行列方向进行铺展
np.tile(a2,(2,3))
# array([[7, 3, 1, 5, 7, 3, 1, 5, 7, 3, 1, 5],
# [3, 9, 4, 1, 3, 9, 4, 1, 3, 9, 4, 1],
# [2, 8, 7, 4, 2, 8, 7, 4, 2, 8, 7, 4],
# [7, 3, 1, 5, 7, 3, 1, 5, 7, 3, 1, 5],
# [3, 9, 4, 1, 3, 9, 4, 1, 3, 9, 4, 1],
# [2, 8, 7, 4, 2, 8, 7, 4, 2, 8, 7, 4]])

参考文章