numpy学习
文章目录
import numpy as np
ndarray
- numpy中定义了一种数据结构
ndarray
,可以看成数组结构。 - ndarray的创建:
# code
arr1 = np.array([1, 2, 3])
arr2 = np.array(range(3))
arr3 = np.arange(3)
arr4 = np.arange(1, 10, 2)
print(type(arr1), type(arr2), type(arr3))
print(arr1)
print(arr2)
print(arr3)
print(arr4)
# result:
<class 'numpy.ndarray'> <class 'numpy.ndarray'> <class 'numpy.ndarray'>
[1 2 3]
[0 1 2]
[0 1 2]
[1 3 5 7 9]
- 注意该数组与python中
list
的不同:
# code:
lst = [1, 2, 3]
print(lst)
# list数据结构是有逗号的,而ndarray没有。
[1, 2, 3]
dtype属性
dtype
属性可以查看数组中的类型,也可指定数组中元素的数据类型。
# code:
print(arr4.dtype)
arr5 = np.array([1, 2], dtype=float)
print(arr5)
print(arr5.dtype)
arr6 = np.array(range(1, 4), dtype='float32')
print(arr6)
print(arr6.dtype)
arr7 = np.array([1, 2, 0], dtype = 'bool')
print(arr7)
print(arr7.dtype)
# 注意:np.arange(4, dtype = bool)这种写法会报错:no fill-function for data-type
# result:
int32
[1. 2.]
float64
[1. 2. 3.]
float32
[ True True False]
bool
astype()方法
- 使用
astype()
方法对数组的数据类型进行转换。
# code:
arr8 = np.arange(3)
arr9 = np.array([-1, 0, 1])
arr10 = arr8.astype(bool)
print(arr8.dtype)
arr11 = arr9.astype(bool)
print(arr10)
print(arr11)
# result:
int32 # 可见astype方法是不改变自身元素类型的,arr8的元素类型还是int32
[False True True]
[ True False True]
生成小数
# code:
import random
arr12 = np.array([random.random() for i in range(6)])
arr13 = np.round(arr12, 3) # 保留三位小数。
print(arr12)
print(arr13)
# result:
[0.90244109 0.33368112 0.63566057 0.40290698 0.35754185 0.7382272 ]
[0.902 0.334 0.636 0.403 0.358 0.738]
shape属性和reshape()方法
# code:
# 1行2列的一维数组
arr1 = np.array([1, 2])
print(arr1)
print(arr1.shape)
# 2行3列的二维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
print(arr2.shape)
print(type(arr2.shape))
# arr2.shape是一个元组,我们可以在reshape方法中传入一个元组来改变数组的结构
arr3 = arr2.reshape((3, 2))
print(arr3)
# 转为一维数组
arr4 = arr3.reshape((6,))
# 这不是一维数组
arr5 = arr3.reshape((1, 6))
print(arr4)
print(arr5)
# result:
[1 2]
(2,)
[[1 2 3]
[4 5 6]]
(2, 3)
<class 'tuple'>
[[1 2]
[3 4]
[5 6]]
[1 2 3 4 5 6]
[[1 2 3 4 5 6]]
多维转一维
- 使用
flatten
方法作用于多维数组并返回一维数组
# code:
arr6 = arr3.flatten()
arr7 = arr5.flatten()
print(arr6)
print(arr7)
# result:
[1 2 3 4 5 6]
[1 2 3 4 5 6]
ndarray的运算
- ndarray与数做运算(广播特性)
# code:
arr1 = np.array([[1, 2], [3, 4]])
arr1 += 2
print(arr1)
# result:
[[3 4]
[5 6]]
- ndarray与ndarray之间的运算
# code:
# 同型数组
arr2 = arr1 * arr1 # 数组不是矩阵
print(arr2)
# 仅仅行或列相同的数组
arr3 = np.arange(4)
arr4 = np.arange(8).reshape((2, 4))
arr5 = arr3 + arr4
print(arr3)
print(arr4)
print(arr5)
# result:
[[ 9 16]
[25 36]]
[0 1 2 3]
[[0 1 2 3]
[4 5 6 7]]
[[ 0 2 4 6]
[ 4 6 8 10]]
ndarray中轴axis
的概念
- 二维数组,形状为(a, b),第一个行数a对应0轴,即0轴有a行,第二个列数b对应1轴,即1轴有b列。
- 对于二维,计算时若
axis = 0
,要把每一行看成一个运算单位(我的理解)。 - 三维数组,形状为(a, b, c),0轴有a片,1轴有b行,2轴有c列。
- 对于三维,计算时若
axis = 0
,要把每一片看成一个计算单位。
#code:
ar = np.arange(6).reshape(2, 3)
print(ar)
print(ar.sum(axis = 0)) # 以行为计算单位,得到一个一维数组
print(ar.sum(axis = 1)) # 以列为计算单位,得到一个一维数组
# result;
[[0 1 2]
[3 4 5]]
[3 5 7]
[3 12]
# code:
ar = np.arange(24).reshape(2, 3, 4)
print(ar)
print(ar.sum(axis = 0)) # 以片为计算单位,得到二维数组
print(ar.sun(axis = 1)) # 以行为计算单位,得到二维数组
print(ar.sun(axis = 2)) # 以列为计算单位,得到二维数组
# result:
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
[[12 14 16 18]
[20 22 24 26]
[28 30 32 34]]
[[12 15 18 21]
[48 51 54 57]]
[[ 6 22 38]
[54 70 86]]
numpy读取文件
file_path = 'D:\\allTest\\ev.csv'
result = np.loadtxt(file_path, delimiter=',', dtype='int')
print(result)
数组的转置
# code:
arr = np.arange(15).reshape((3, 5))
# 方法1
print(arr.transpose())
# 方法2
print(arr.T)
# 方法3
print(arr.swapaxes(1, 0))
# result:
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
numpy中数组的索引和切片
arr = np.arange(15).reshape((3, 5))
# 取数组的某一行(取出的数据仍是ndarray)
print(arr[0])
# 取指定的多行
print(arr[[0, 2]])
# 取连续的多行
print(arr[1:])
# result:
[0 1 2 3 4]
[[ 0 1 2 3 4]
[10 11 12 13 14]]
[[ 5 6 7 8 9]
[10 11 12 13 14]]
# 取列
print(arr[:,0])
# 取多列
print(arr)
print(arr[:,1:3])
print(arr[:,1::2])
# 取指定多列
print(arr[:,[0, 2, 3]])
[ 0 5 10]
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
[[ 1 2]
[ 6 7]
[11 12]]
[[ 1 3]
[ 6 8]
[11 13]]
[[ 0 2 3]
[ 5 7 8]
[10 12 13]]
# 取某行某列
print(arr[1,2])
print(type(arr[1,2])) # 注意类型
# 取多行多列(注意在[,]中逗号的左右两边有一边是以":"形式写的,则结果是行列交叉的效果,行列的个数可以不相同)
print(arr[0:2,0::2])
print(arr[0:2,[2, 4]])
# arr[[0, 1],[0, 1, 2]]这种写法会出现错误,因为左右两边的行列个数不相同。
print(arr[[0, 2],[1, 3]]) # 左右两边个数相同,得到两个点(0,1)和(2,3)。可用此法得到不连续的点.
# result:
7
<class 'numpy.int32'>
[[0 2 4]
[5 7 9]]
[[2 4]
[7 9]]
[ 1 13]
数组值的修改与bool索引
# 把数组的第一行改为0
arr[1] = 0
print(arr)
# 布尔索引
print(arr > 0)
# 把数组中大于10的数改为0
arr[arr > 10] = 0 # 索引可以是bool型
print(arr)
[[ 0 1 2 3 4]
[ 0 0 0 0 0]
[10 11 12 13 14]]
[[False True True True True]
[False False False False False]
[ True True True True True]]
[[ 0 1 2 3 4]
[ 0 0 0 0 0]
[10 0 0 0 0]]
numpy中的三元运算符
# 把arr中等于0的数字改为1,否则改为0
arr2 = np.where(arr == 0, 1, 0)
print(arr2)
[[1 0 0 0 0]
[1 1 1 1 1]
[0 1 1 1 1]]
clip操作
arr = np.arange(12).reshape((3, 4))
# 将arr中大于6的数改为6,将小于4的数改为4
arr2 = arr.clip(4, 6)
print(arr2)
[[4 4 4 4]
[4 5 6 6]
[6 6 6 6]]
数组的拼接
arr1 = np.arange(6).reshape((2, 3))
arr2 = np.arange(7, 13).reshape((2, 3))
print(arr1)
print(arr2)
# 按行的顺序,一行行的往下拼接
print(np.vstack((arr1, arr2)))
# 按列的顺序,一列列的从左往右拼接
print(np.hstack((arr1, arr2)))
[[0 1 2]
[3 4 5]]
[[ 7 8 9]
[10 11 12]]
[[ 0 1 2]
[ 3 4 5]
[ 7 8 9]
[10 11 12]]
[[ 0 1 2 7 8 9]
[ 3 4 5 10 11 12]]
数组的行列交换
# 交换第一行和第二行
arr1[[0, 1],:] = arr1[[1, 0],:]
print(arr1)
# 交换第一列和第二列
arr1[:,[0, 1]] = arr1[:,[1, 0]]
print(arr1)
[[3 4 5]
[0 1 2]]
[[4 3 5]
[1 0 2]]
特别的数组
全1或全0的数组
arr1 = np.zeros((3, 4))
arr2 = np.ones((2, 3))
print(arr1)
print(arr2)
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[1. 1. 1.]
[1. 1. 1.]]
创建对角线为1的正方形数组
arr = np.eye(3)
print(arr)
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
获取最大值最小值
arr = np.array([[2, 3, 7],[1, 9, 0],[3, 4, 5],[6, 0, 2]])
print(arr)
print(arr.max())
print(np.max(arr, axis = 1))
print(arr.min(axis = 0))
[[2 3 7]
[1 9 0]
[3 4 5]
[6 0 2]]
9
[7 9 5 6]
[1 0 0]
获取最大值,最小值的位置
print(arr.argmax()) # 不指定轴的话,返回的位置是在扁平数组中的位置。
print(np.argmin(arr, axis = 0))
print(arr.argmax(axis = 1))
4
[1 3 1]
[2 1 2 0]
随机数数组
from numpy import random as rd
# 0~1范围内的随机数的数组
arr = rd.rand(3, 4)
print(arr)
# 平均数为0,标准差为1的正态分布的随机数的数组
print(rd.randn(2, 3))
# 给定范围和形状的均匀分布的数组
print(rd.uniform(2, 3, (1, 3)))
# 给定范围和形状的随机整数
print(rd.randint(2, 10, (3, 4)))
# 设置随机种子,相同的随机种子得到的随机数是一样的
for i in range(3):
rd.seed(5)
print(rd.randint(2, 6, (3, 4)))
[[0.62878791 0.57983781 0.5999292 0.26581912]
[0.28468588 0.25358821 0.32756395 0.1441643 ]
[0.16561286 0.96393053 0.96022672 0.18841466]]
[[ 0.99643983 0.71242127 0.05914424]
[-0.36331088 0.00328884 -0.10593044]]
[[2.63979518 2.9856244 2.2590976 ]]
[[7 3 3 7]
[9 2 8 8]
[4 9 3 8]]
[[5 4 5 3]
[4 4 2 3]
[2 2 5 4]]
[[5 4 5 3]
[4 4 2 3]
[2 2 5 4]]
[[5 4 5 3]
[4 4 2 3]
[2 2 5 4]]
copy和view
# 直接赋值,赋予的是地址,两个变量会相互影响
arr1 = np.arange(4).reshape((2, 2))
arr2 = arr1
print(arr1)
print(arr2)
arr2[0] = 1
print(arr1)
print(arr2)
print('-' * 20)
# 视图操作也会相互影响
arr3 = arr2[:]
print(arr3)
arr3[0] = 0
print(arr1)
print(arr2)
print(arr3)
print('-'* 20)
# 使用copy则会另开辟空间来存储被赋予的数据,两个变量之间的地址不一样了,不相互影响。
arr4 = arr3.copy()
print(arr4)
arr4[0] = -1
print(arr4)
print(arr3)
[[0 1]
[2 3]]
[[0 1]
[2 3]]
[[1 1]
[2 3]]
[[1 1]
[2 3]]
--------------------
[[1 1]
[2 3]]
[[0 0]
[2 3]]
[[0 0]
[2 3]]
[[0 0]
[2 3]]
--------------------
[[0 0]
[2 3]]
[[-1 -1]
[ 2 3]]
[[0 0]
[2 3]]
numpy中的nan
- nan就是not a number 的意思
- nan == nan 返回False
- nan与任何数运算为nan
# 统计数组中nan的个数
arr = np.array([[1, 2, 3],[4, np.nan, np.nan]])
print(np.count_nonzero(arr != arr)) # 2
print(np.count_nonzero(np.isnan(arr))) # 2
numpy中常用的统计函数
-
求和
array.sum(axis = ?)
-
最大值,最小值
array.max(axis = ?)
array.min(axis = ?)
-
均值
array.mean(axis = ?)
-
中值
np.median(array, axis = ?)
-
极值(最大值最小值之差)
np.ptp(array, axis = ?)
-
标准差: 1 n ∑ i = 1 n ( x i − μ ) 2 \sqrt{\frac{1}{n}\sum_{i=1}^{n}\left ( x_{i}-\mu \right )^{2}} n1∑i=1n(xi−μ)2 :
array.std(axis = ?)
练习
- 将二维数组中值为nan的位置替换为该列的均值
# code:
# 将数组中的nan换为该列的均值
import numpy as np
def trans_nan(array):
# 判断是二维数组
if array.ndim == 2:
# 以列为单位进行遍历
for i in range(array.shape[1]):
# 获取每一列的切片
array_temp = array[:,i]
# 计算该列nan的个数
num_nan = np.count_nonzero(np.isnan(array_temp))
# 如果全是nan则该列置为0
if num_nan == array.shape[0]:
# 记得要写切片形式
array_temp[:] = 0
else:
# 获取不含nan的切片
array_temp_nonan = array_temp[array_temp == array_temp]
# 计算平均值
value_average = array_temp_nonan.mean()
# 将均值赋给原来位置的nan
array_temp[np.isnan(array_temp)] = value_average # 原array相应位置的nan改变了
array = np.array([[1, np.nan, 3], [2, 5, np.nan], [1, 1, 0]])
print(array)
trans_nan(array)
print(array)
# reslut:
[[ 1. nan 3.]
[ 2. 5. nan]
[ 1. 1. 0.]]
[[1. 3. 3. ]
[2. 5. 1.5]
[1. 1. 0. ]]