数组操作

  • 修改数字形状
  • 翻转数组
  • 修改数组维度
  • 连接数组
  • 分割数组
  • 数组的添加与删除

修改数字形状

函数 说明
reshape 在不改变数据的条件下修改形状
flat 数组元素迭代器
flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
ravel 返回展开数组

1> numpy.reshape

语法:

numpy.reshape(arr,newshape,order='A')

参数 说明
arr 要修改形状的数组
newshape 整数或整数数组,新的形状应兼容原有形状
order C : 行方向
F : 列方向
A : 任意方向(默认)
K : 元素在内存中的出现顺序
num_np = np.arange(8)
print('原始数组:\n{}'.format(num_np))
mod_up = num_np.reshape(4, 2)
print('修改后的数组:\n{}'.format(mod_up))

# 输出结果:
# 原始数组:
# [0 1 2 3 4 5 6 7]
# 修改后的数组:
# [[0 1]
#  [2 3]
#  [4 5]
#  [6 7]]

2> numpy.ndarray.flat

数组元素的迭代器

np_ar = np.arange(4).reshape(2, 2)
print('原始数组:')
for row in np_ar:
    print(row)

print('迭代后的数组:')
for ele in np_ar.flat:
    print(ele)

# 输出结果:
# 原始数组:
# [0 1]
# [2 3]
# 迭代后的数组:
# 0
# 1
# 2
# 3

3> numpy.ndarray.flatten

返回一份数组拷贝,对拷贝所做的修改不会影响原始数组

语法:

ndarray.flatten(order = 'C')

参数 说明
order C : 行方向
F : 列方向
A : 任意方向(默认)
K : 元素在内存中的出现顺序
num_np = np.arange(8).reshape(2,4)
print('原数组:\n{}'.format(num_np))

# 默认按行
print('展开的数组:\n{}'.format(num_np.flatten()))
print('以 Fortran 语言风格顺序展开的数组: \n{}'.format(num_np.flatten(order = 'F')))

# 输出结果:
#  原数组:
#  [[0 1 2 3]
#   [4 5 6 7]]
#  展开的数组:
#  [0 1 2 3 4 5 6 7]
#  以 Fortran 语言风格顺序展开的数组: 
#  [0 4 1 5 2 6 3 7]

4> numpy.ravel

返回展开的数组,修改会影响原始数组

num_np = np.arange(8).reshape(2,4)
print('原数组:\n{}'.format(num_np))

# 默认按行
print('调用 ravel函数之后:\n{}'.format(num_np.ravel()))
print('以 Fortran 语言风格顺序调用 ravel函数之后: \n{}'.format(num_np.ravel(order = 'F')))

# 输出结果:
#  原数组:
#  [[0 1 2 3]
#   [4 5 6 7]]
#  调用 ravel函数之后:
#  [0 1 2 3 4 5 6 7]
#  以 Fortran 语言风格顺序调用 ravel函数之后: 
#  [0 4 1 5 2 6 3 7]

翻转数组

函数 说明
transpose 对换数组的维度
ndarray.T 对换数组的维度
rollaxis 向后滚动指定的轴
swapaxes 对换数组的两个轴

1> numpy.transpose()

语法:

numpy.transpose(arr,axes)

参数 说明
arr 要操作的数组
axes 整数列表,对应维度,通常所有的维度都会对换
num_np = np.arange(12).reshape(3,4)
print('原始数组:\n{}'.format(num_np))
print('对换数组:\n{}'.format(np.transpose(num_np)))

# 输出结果:
#  原始数组:
#  [[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#  对换数组:
#  [[ 0  4  8]
#   [ 1  5  9]
#   [ 2  6 10]
#   [ 3  7 11]]

2> numpy.ndarray.T()

num_np = np.arange(12).reshape(3,4)
print('原始数组:\n{}'.format(num_np))
print('对换数组:\n{}'.format(num_np.T))

# 输出结果:
#  原始数组:
#  [[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#  对换数组:
#  [[ 0  4  8]
#   [ 1  5  9]
#   [ 2  6 10]
#   [ 3  7 11]]

3> numpy.rollaxis()

语法:

numpy.rollaxis(arr, axis, start)

np_3d = np.arange(8).reshape(2,2,2)
print('原数组:\n{}'.format(np_3d))

# 输出结果:
#  原数组:
#  [[[0 1]
#    [2 3]]

#   [[4 5]
#    [6 7]]]

# 将轴 2 滚动到轴 0(宽度到深度)
print('调用 rollaxis 函数:\n{}'.format(np.rollaxis(np_3d,2)))

# 输出结果:
#  调用 rollaxis 函数:
#  [[[0 2]
#    [4 6]]

#   [[1 3]
#    [5 7]]]

# 将轴 0 滚动到轴 1(宽度到高度)
print('调用 rollaxis 函数:\n{}'.format(np.rollaxis(np_3d,2,1)))
# 输出结果:
#  调用 rollaxis 函数:
#  [[[0 2]
#    [1 3]]

#   [[4 6]
#    [5 7]]]

4> numpy.swapaxes()

语法:

numpy.swapaxes(arr,axis1,axis2)

参数 说明
arr 要操作的数组
axes1 对应第 1 个轴的整数
axis2 对应第 2 个轴的整数
np_3d = np.arange(8).reshape(2,2,2)
print('原数组:\n{}'.format(np_3d))
# 交换轴 2 和轴 0
print('调用 swapaxes 函数:\n{}'.format(np.swapaxes(np_3d,2,0)))

# 输出结果:
#  原数组:
#  [[[0 1]
#    [2 3]]

#   [[4 5]
#    [6 7]]]
#  调用 rollaxis 函数:
#  [[[0 4]
#    [2 6]]

#   [[1 5]
#    [3 7]]]

修改数组维度

函数 说明
broadcast 产生模仿广播的对象
broadcast_to 将数组广播为新形状
Expand_dims 扩展数组的形状
squeeze 从数组的形状删除一维条目

1> numpy.broadcast()

x_np = np.array([[1],[2],[3]])
y_np = np.array([4, 5, 6])
# 对 y_np 广播 x_np
b_np = np.broadcast(x_np,y_np)
for u,v in b_np:
    print(u,v)

# 输出结果:
#  1 4
#  1 5
#  1 6
#  2 4
#  2 5
#  2 6
#  3 4
#  3 5
#  3 6

2> numpy.broadcast_to()

将数组广播为新形状,在原始数组上返回只读数组

语法:

numpy.broadcast_to(array, shape, subok)

num_np = np.arange(4).reshape(1,4)
print('原数组:\n{}'.format(num_np))
br_to_np = np.broadcast_to(num_np,(4,4))
print('调用 broadcast_to 函数以后:\n{}'.format(br_to_np))

# 输出结果:
#  原数组:
#  [[0 1 2 3]]
#  调用 broadcast_to 函数以后:
#  [[0 1 2 3]
#   [0 1 2 3]
#   [0 1 2 3]
#   [0 1 2 3]]

3> numpy.expand_dims()

通过在指定位置插入新的轴来扩展数组形状

语法:

numpy.expand_dims(arr,axis)

参数 说明
arr 输入数组
axis 新轴插入的位置
x_np = np.array(([1,2],[3,4]))
print('数组 x_np:\n{}'.format(x_np))

# 输出结果:
#  数组 x_np:
#  [[1 2]
#   [3 4]]

y_np = np.expand_dims(x_np,axis = 0)
print('数组 y_np:\n{}'.format(y_np))

# 输出结果:
#  数组 y_np:
#  [[[1 2]
#    [3 4]]]

z_np = np.expand_dims(x_np,axis = 1)
print('数组 z_np:\n{}'.format(z_np))

# 输出结果:
#  数组 z_np:
#  [[[1 2]]

#   [[3 4]]]

4> numpy.squeeze()

语法:

numpy.squeeze(arr,axis)

参数 说明
arr 输入数组
axis 整数或整数元祖,用于选择形状中一维条目的子集
x_np = np.arange(9).reshape(1,3,3)
print('数组 x_np:\n{}'.format(x_np))

# 输出结果:
#  数组 x_np:
#  [[[0 1 2]
#    [3 4 5]
#    [6 7 8]]]

y_np = np.squeeze(x_np)
print('应用 squeese 后的数组:\n{}'.format(y_np))

# 输出结果:
#  应用 squeese 后的数组:
#  [[0 1 2]
#   [3 4 5]
#   [6 7 8]]

连接数组

函数 说明
concateate 连接沿现有轴的数组序列
stack 沿着新轴连接数组序列
hstack 水平堆叠序列中的数组(列方向)
vstack 垂直堆叠序列中的数组(行方向)

1> numpy.concateate()

语法:

numpy.concateate((a1,a2,...),axis)

参数 说明
a1,a2,... 相同类型的数组
axis 沿该轴连接数组,默认为 0
np_1 = np.array([[1, 2],[3, 4]])
print('第 1 个数组:\n{}'.format(np_1))

# 输出结果:
#  第 1 个数组:
#  [[1 2]
#   [3 4]]

np_2 = np.array([[5, 6],[7, 8]])
print('第 2 个数组:\n{}'.format(np_2))

# 输出结果:
#  第 2 个数组:
#  [[5 6]
#   [7 8]]

print('沿着轴 0连接两个数组:\n{}'.format(np.concatenate((np_1,np_2))))

# 输出结果:
#  沿着轴 0连接两个数组:
#  [[1 2]
#   [3 4]
#   [5 6]
#   [7 8]]

print('沿着轴 1连接两个数组:\n{}'.format(np.concatenate((np_1,np_2),axis = 1)))

# 输出结果:
#  沿着轴 0连接两个数组:
#  [[1 2 5 6]
#   [3 4 7 8]]

2> numpy.stack()

沿着新轴连接数组序列

语法:

numpy.stack(arrays,axis)

参数 说明
arr 相同形状的数组序列
axis 返回数组中的轴,输入数组沿着它堆叠
np_1 = np.array([[1, 2],[3, 4]])
print('第 1 个数组:\n{}'.format(np_1))

# 输出结果:
#  第 1 个数组:
#  [[1 2]
#   [3 4]]

np_2 = np.array([[5, 6],[7, 8]])
print('第 2 个数组:\n{}'.format(np_2))

# 输出结果:
#  第 2 个数组:
#  [[5 6]
#   [7 8]]

print('沿着轴 0堆叠两个数组:\n{}'.format(np.stack((np_1,np_2))))


# 输出结果:
#  沿着轴 0堆叠两个数组:
#  [[[1 2]
#    [3 4]]

#   [[5 6]
#    [7 8]]]

print('沿着轴 1堆叠两个数组:\n{}'.format(np.stack((np_1,np_2),axis = 1)))

# 输出结果:
#  沿着轴 1堆叠两个数组:
#  [[[1 2]
#    [5 6]]

#   [[3 4]
#    [7 8]]]

3> numpy.hstack()

水平堆叠生成数组

语法:

numpy.hstack(tup)

参数 说明
tup 元祖,列表,或者 numpy 数组
np_1 = np.array([[1, 2],[3, 4]])
print('第 1 个数组:\n{}'.format(np_1))

# 输出结果:
#  第 1 个数组:
#  [[1 2]
#   [3 4]]

np_2 = np.array([[5, 6],[7, 8]])
print('第 2 个数组:\n{}'.format(np_2))

# 输出结果:
#  第 2 个数组:
#  [[5 6]
#   [7 8]]

print('水平堆叠:\n{}'.format(np.hstack((np_1,np_2))))

# 输出结果:
#  水平堆叠:
#  [[1 2 5 6]
#   [3 4 7 8]]

4> numpy.vstack()

垂直堆叠生成数组

语法:

numpy.vstack(tup)

参数 说明
tup 元祖,列表,或者 numpy 数组
np_1 = np.array([[1, 2],[3, 4]])
print('第 1 个数组:\n{}'.format(np_1))

# 输出结果:
#  第 1 个数组:
#  [[1 2]
#   [3 4]]

np_2 = np.array([[5, 6],[7, 8]])
print('第 2 个数组:\n{}'.format(np_2))

# 输出结果:
#  第 2 个数组:
#  [[5 6]
#   [7 8]]

print('垂直堆叠:\n{}'.format(np.vstack((np_1,np_2))))

# 输出结果:
#  垂直堆叠:
#  [[1 2]
#   [3 4]
#   [5 6]
#   [7 8]]

分割数组

函数 说明
split 将 1 个数组分割为多个子数组
hsplit 将 1 个数组水平分割成多个子数组(按列)
vsplit 将 1 个数组垂直分割成多个子数组(按行)

1> numpy.split()

语法:

numpy.split(array, indices_or_sections, axis)

参数 说明
array 被分割的数组
indices_or_sections 如果是一个整数,则用该数平均分割;如果是 1 个数组,则沿轴分割的位置分割(左开右闭)
axis 沿着某一维度进行分割.如果为 0,横向分割,默认为 1,纵向分割
num_np = np.arange(9)
print('原始数组:\n{}'.format(num_np))
print('将数组分为三个大小相等的子数组:\n{}'.format(np.split(num_np,3)))
print('将数组在一维数组中表明的位置分割:\n{}'.format(np.split(num_np,[4,7])))

# 输出结果:
#  原始数组:
#  [0 1 2 3 4 5 6 7 8]
#  将数组分为三个大小相等的子数组:
#  [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
#  将数组在一维数组中表明的位置分割:
#  [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]

2> numpy.hsplit()

用于水平分割数组,通过指定要返回的相同形状的数组数量拆分原数组

num_np = np.floor(10*np.random.random((2,6)))
print('原始数组:\n{}'.format(num_np))
print('水平分割后:\n{}'.format(np.hsplit(num_np,3)))

# 输出结果:
#  原始数组:
#  [[3. 6. 0. 7. 6. 2.]
#   [5. 4. 5. 3. 1. 6.]]
#  水平分割后:
#  [array([[3., 6.],
#         [5., 4.]]), array([[0., 7.],
#         [5., 3.]]), array([[6., 2.],
#         [1., 6.]])]

2> numpy.vsplit()

沿着垂直轴分割数组,通过指定要返回的相同形状的数组数量拆分原数组

num_np = np.arange(16).reshape(4,4)
print(f'原始数组:{num_np}')
print(f'垂直分割后:{np.vsplit(num_np,2)}')

# 输出结果:
#  原始数组:[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]
#   [12 13 14 15]]
#  垂直分割后:[array([[0, 1, 2, 3],
#         [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
#         [12, 13, 14, 15]])]

数组的添加与删除

函数 说明
resize 返回指定大小的新数组
append 将值添加到数组末尾
insert 沿指定轴将值插入指定下标之前
delete 删掉某个轴的子数组,并返回删除后的新数组
unique 查找数组内的唯一元素

1> numpy.resize()

返回指定大小的新数组,如果新数组大小大于原始数组大小,则包含原始数组中的元素的副本

first_np = np.array([[1, 2, 3],[4, 5, 6]])
print(f'第一个数组:\n{first_np}')

# 输出结果:
#  第一个数组:
#  [[1 2 3]
#   [4 5 6]]

second_np = np.resize(first_np,(3,2))
print(f'第二个数组:\n{second_np}')

# 输出结果:
#  第二个数组:
#  [[1 2]
#   [3 4]
#   [5 6]]

third_np = np.resize(first_np,(3,3))
print(f'第二个数组:\n{third_np}')

# 输出结果:
#  第二个数组:
#  [[1 2 3]
#   [4 5 6]
#   [1 2 3]]

2> numpy.append()

在数组的末尾添加值,输入数组的维度必须匹配

语法:

numpy.append(arr,values,axis = None)

参数 说明
arr 输入数组
values 向 arr 添加值,需要和 arr 形状相同
axis 默认为 None,当 axis 无定义时,横向添加,返回的是一维数组;当 axis 有定义时,分别为 0 和 1,当 axis 为 1 时,数组加在右边(行数要相同)
num_np = np.array([[1, 2, 3],[4, 5, 6]])
print(f'原始数组:\n{num_np}')

# 输出结果:
#  原始数组:
#  [[1 2 3]
#   [4 5 6]]

print(f'向数组添加元素:\n{np.append(num_np,[7, 8, 9])}')

# 输出结果:
#  向数组添加元素:
#  [1 2 3 4 5 6 7 8 9]

print(f'沿着轴 0 添加元素:\n{np.append(num_np,[[7,8,9]],axis = 0)}')

# 输出结果:
#  沿着轴 0 添加元素:
#  [[1 2 3]
#   [4 5 6]
#   [7 8 9]]

print(f'沿着轴 1 添加元素:\n{np.append(num_np,[[5, 5, 5],[7, 8, 9]],axis = 1)}')

# 输出结果:
#  沿着轴 1 添加元素:
#  [[1 2 3 5 5 5]
#   [4 5 6 7 8 9]]

3> numpy.insert()

在给定索引之前,沿指定轴在输入数组中插入值

语法:

numpy.insert(arr,obj,values,axis)

参数 说明
arr 输入数组
obj 在其之前插入值的索引
values 要插入的值
axis 沿该轴插入数组,如果未提供,则输入数组会被展开
num_np = np.array([[1, 2],[3, 4],[5, 6]])
print(f'原始数组:\n{num_np}')

# 输出结果:
#  原始数组:
#  [[1 2]
#   [3 4]
#   [5 6]]

print(f'未传入 axis 参数,在插入之前输入数组会被展开:\n{np.insert(num_np,3,[11,12])}')

# 输出结果:
#  未传入 axis 参数,在插入之前输入数组会被展开:
#  [ 1  2  3 11 12  4  5  6]

print('传递 axis 参数')
print(f'沿轴 0 传播:\n{np.insert(num_np, 1, [11],axis = 0)}')

# 输出结果:
#  沿轴 0 传播:
#  [[ 1  2]
#   [11 11]
#   [ 3  4]
#   [ 5  6]]

print(f'沿轴 1 传播:\n{np.insert(num_np, 1, [11],axis = 1)}')
# 输出结果:
#  沿轴 1 传播:
#  [[ 1 11  2]
#   [ 3 11  4]
#   [ 5 11  6]]

4> numpy.delete()

返回从输入数组中删除指定子数组的新数组

语法:

numpy.delete(arr,obj,axis)

参数 说明
arr 输入数组
obj 可以被切片,整数或整数数组,表明要从数组删除子数组
axis 沿该轴插入数组,如果未提供,则输入数组会被展开
num_np = np.arange(12).reshape(3,4)
print(f'初识数组:\n{num_np}')

# 输出结果:
#  初识数组:
#  [[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]

print(f'未传入 axis 参数,在删除之前输入数组会被展开:\n{np.delete(num_np,3)}')

# 输出结果:
#  未传入 axis 参数,在删除之前输入数组会被展开:
#  [ 0  1  2  4  5  6  7  8  9 10 11]

print(f'删除第二列:\n{np.delete(num_np,1,axis = 1)}')

# 输出结果:
#  删除第二列:
#  [[ 0  2  3]
#   [ 4  6  7]
#   [ 8 10 11]]

num_np1 = np.arange(1,10)
print(np.delete(num_np1,np.s_[::2]))  # 输出结果: [2 4 6 8]

5> numpy.unique()

返回输入数组中的去重元素数组

numpy.unique(arr, return_index, return_inverse, return_counts)

参数 说明
arr 输入数组,如果不是一维数组则会展开
return_index 如果为 True,则返回输入数组中的元素下标
return_inverse 如果为 True,则返回去重数组的下标,用于重构输入数组
return_counts 如果为 True,则返回去重数组中的元素在原数组中的出现次数
num_np = np.array([5, 2, 6, 2, 7, 5, 6, 8, 2, 9])
print(f'原始数组:{num_np}')

# 输出结果:
#  原始数组:[5 2 6 2 7 5 6 8 2 9]

print(f'数组去重:\n{np.unique(num_np)}')

# 输出结果:
#  数组去重:
#  [2 5 6 7 8 9]

print('去重数组的索引数组:')
unique_np,indices = np.unique(num_np,return_index = True)
print(unique_np)  #  输出结果: [2 5 6 7 8 9]
print(indices)    #  输出结果: [1 0 2 4 7 9]

print('去重数组的下标:')
unique_np,indices = np.unique(num_np,return_inverse = True)
print(unique_np)  #  输出结果: [2 5 6 7 8 9]
print(indices)    #  输出结果: [1 0 2 0 3 1 2 4 0 5]
print(f'使用下标重构原数组:{unique_np[indices]}')  # 输出结果: 使用下标重构原数组:[5 2 6 2 7 5 6 8 2 9]

print('返回去重元素的重复数量:')
unique_np,indices = np.unique(num_np,return_counts = True)
print(unique_np)  #  输出结果: [2 5 6 7 8 9]
print(indices)    #  输出结果: [3 2 2 1 1 1]