一个在python中做科学计算的基础库,重在数值计算,也是大部分python科学技术库的基础库,多用在大型、多维数组上执行数值运算。

广播原则:

如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。

可以把维度看成shape所对应的数字的个数。

import numpy as np
# 一维数组
t1=np.arange(12)
print(t1)
print(t1.shape)

# 二维数组
print('*'*50)
t2=np.array([[1,2,3],[4,5,6]])
print(t2)
print(t2.shape)

# 三维数组
print('*'*50)
t3=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(t3)
print(t3.shape)

# 改变数组的形状 reshape()返回新的数组
print('*'*50)
t4=np.arange(12).reshape((3,4))
print(t4)
print(t4.shape)

print('*'*50)
t5=np.arange(24).reshape((2,3,4))
print(t5)
print(t5.shape)

print('*'*50)
# reshape(24,)和reshape(24,1)是两个不同的结果,一个是一维数组,由24个元素组成,一个是二维数组,每组只有一个元素
print(t5.reshape((24,))) # [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 这是一维数组
print(t5.reshape((24,1)))
print(t5.reshape((1,24))) # [[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]] 这是二维数组

print('*'*50)
# 多维维数组转成一维数组
t6=t5.reshape((t5.shape[0]*t5.shape[1]*t5.shape[2],))
print(t6)
print(t6.shape)

t7=t5.flatten()
print(t7)
print(t7.shape)

print('*'*50)
# 数组与数字进行运算,数组中的每个元素与数字做对应的运算
print(t5)
print(t5+2)
print(t5-2)
print(t5*2)
print(t5/2)
# print(t5/0)  # 其中0/0 得到的结果为nan not a number,非0/0 得到的结果是inf 无限

print('*'*50)
# 相同形状的两个数组做数学运算,就是两个数组对应位置的元素做相应的运算
print(t5)
t8=np.arange(100,124).reshape((2,3,4))
print(t5+t8)
print(t5-t8)
print(t5*t8)
print(t5/t8)

print('*'*50)
# 一维数组中元素个数与多维数组中最后一个维度的元素个数相等,则进行相应的运算。
# 多维每一行对应的位置的元素与一维数组中对应的元素进行运算  相当于行对应位置运算
print(t5)
t9=np.arange(1,5) # 一维数组 4个元素 [1 2 3 4]
print(t9)
print(t9.shape)
print(t5+t9)
print(t5-t9)
print(t5*t9)
print(t5/t9)

print('*'*50)
# 二维数组 多行一列情况中行的个数与多维数组中倒数第二个维度的数值相等,则进行相应的运算
# 二维数组中的元素与对应列位置上的元素进行运算,相当于列对应位置运算
print(t5)
t10=np.arange(1,4).reshape((3,1)) # 二维数组,3行1列
print(t10)
print(t10.shape)
print(t5+t10)
print(t5-t10)
print(t5*t10)
print(t5/t10)
# 总结:数组与数组进行运算,要么数组的形状要么相同,要么行维度或列维度相同,否则不能进行运算。 (a,b,c)可以和(b,c)或(c,)或(b,1)进行运算

在numpy中可以理解为方向,使用0,1,2...数字表示。对于一个一维数组,只有一个0轴,对于二维数组,有0轴和1轴,对于三维数组,有0,1,2轴。

csv:comma-separateed value,逗号分隔值文件

显示:表格状态

源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录。

import numpy as np
'''
fname:文件、执法车或产生器、可以是压缩文件
dtype:数据类型。可选,csv的字符串以什么数据类型读入数组中。默认np.float
delimeter:分隔字符串,默认是任何空格
skiprows:跳过多少行,一般跳过第一行表头
usecols:读取指定的列,索引。元组类型
unpack:转置。如果为True,读入属性将分别写入不同数组变量,False 读入数据只写入一个数组变量。默认为False
'''
f=np.loadtxt(fname='./**.csv',dtype='int',delimiter=',',skiprows=0,usecols=None,unpack=False)
print(f)

转置

转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的是为了更方便的去处理数据。

转置三种方式:

1,T属性  t.T

2,transpose()方法 t.tanspose()

3,swapaxes()方法 t.swapaxes(1,0)

import numpy as np

t1=np.arange(24).reshape(4,6)
print(t1)

print('*'*50)
# 方法一:T属性
t2=t1.T
print(t2)

# 方法二:transpose()方法
print('*'*50)
t3=t1.transpose()
print(t3)

print('*'*50)
# 方法三:swapaxes()方法
t4=t1.swapaxes(1,0)
print(t4)

索引和切片

import numpy as np

a=np.arange(12).reshape(3,4)
print(a)

print('*'*50)
# 取某一行
print(a[1]) #[4 5 6 7]

print('*'*50)
# 取多行
print(a[0:2])

print('*'*50)
# 取指定行
print(a[[0,2]])

print('*'*50)
# 取一列
print(a[:,1])

print('*'*50)
#取多列
print(a[:,1:3])

print('*'*50)
# 取指定列
print(a[:,[0,2]])

print('*'*50)
# 取第一行第二列的数据
print(a[0,1])

print('*'*50)
# 取多行多列 第二行到第三行,第二列到第四列 [1:3) [1:4)
print(a[1:3,1:4])

print('*'*50)
# 取不相邻的点 取得(1,0)和(2,2)两个位置上的数据
print(a[[1,2],[0,2]])

修改值

import numpy as np

t=np.arange(12).reshape(3,4)
print(t)

print('*'*50)
# 将第一行至第三行的数据赋值为100
t[1:3,]=100
print(t)

print('*'*50)
# 将第一列和第二列的数据赋值为200
t[:,0:2]=200
print(t)

print('*'*50)
# 将(1,2)和(2,4)位置上数据赋值为300
t[[1,2],[2,3]]=300
print(t)

print('*'*50)
# t<10 的结果  元素小于10则值为True,反之为False
print(t<10)
'''
[[False False  True  True]
 [False False False False]
 [False False False False]]
'''

print('*'*50)
# t[t<10] 的结果 数组中符合条件的数据
print(t[t<10])
print(type(t[t<10]))  # <class 'numpy.ndarray'>

print('*'*50)
# 将数组中数值大于200的元素数据改为210
t[t>200]=210
print(t)

print('*'*50)
# 三元运算符 np.where(t>200,250,100) 数组中大于250的数据改为250,反之改为100
t1=np.where(t>200,250,100) # 有返回值
print(t1)

print('*'*50)
# 裁剪clip() t.clip(100,200) 小于100的替换为100,大于200的替换为200
print(t)
t2=t.clip(80,208)
print(t2)

数组的拼接

import numpy as np

t1=np.arange(10).reshape(2,5)
t2=np.arange(20,30).reshape(2,5)
# 数组横向拼接
print(t1)
'''
[[0 1 2 3 4]
 [5 6 7 8 9]]
'''
print(t2)
'''
[[20 21 22 23 24]
 [25 26 27 28 29]]
'''

print('*'*50)
# 数组纵向拼接(vertical) np.vstack()
t3=np.vstack((t1,t2))
print(t3)
'''
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [20 21 22 23 24]
 [25 26 27 28 29]]
'''

print('*'*50)
# 数组横向拼接(Horizonta) np.hstack()
t4=np.hstack((t1,t2))
print(t4)
'''
[[ 0  1  2  3  4 20 21 22 23 24]
 [ 5  6  7  8  9 25 26 27 28 29]]
'''

print('*'*50)
t6=np.arange(6).reshape((2,3))
t7=np.arange(9).reshape((3,3))
t8=np.arange(8).reshape((2,4))
print(t6)
print(t7)
print(t8)
print('*'*50)
t9=np.vstack((t6,t7))
t10=np.hstack((t6,t8))
print(t9)
'''
[[0 1 2]
 [3 4 5]
 [0 1 2]
 [3 4 5]
 [6 7 8]]
'''
print(t10)
'''
[[0 1 2 0 1 2 3]
 [3 4 5 4 5 6 7]]
'''
# 总结:纵向拼接(np.vstack()) 要求两个数组的列的个数一致;横向拼接(np.hstack()) 要求两个数组的行的个数一致

数组的行列交换

import numpy as np

t=np.arange(20).reshape(4,5)
print(t)

print('*'*50)
# 行交换  相当于第三行的数据赋值给第一行,第一行的数据赋值给第三行
t[[0,2],:]=t[[2,0],:]
print(t)

print('*'*50)
#  列交换 相当于第二列的数据赋值给第一列,第一列的数据赋值给第二列
t[:,[0,1]]=t[:,[1,0]]
print(t)
# 总结:原理还是赋值

 常见方法

import numpy as np
import random
# 创建一个全是0的数组 np.zeros()
t1=np.zeros((3,4))
print(t1)

print('*'*50)
# 创建一个全是1的数组 np.ones()
t2=np.ones((3,4))
print(t2)

print('*'*50)
# 创建一个对角线为1的正方形数组(方阵)np.eye()
t3=np.eye(3)
print(t3)

print('*'*50)
# 获取最大值或最小值的位置
t=np.array([random.randint(10,50) for _ in range(24)]).reshape(4,6)
print(t)
t_max_index=np.argmax(t,axis=0)
print(t_max_index)
t_min_index=np.argmin(t,axis=1)
print(t_min_index)

numpy生成随机数

import numpy as np
#rand(d0,d1...dn) 创建d0-dn维度的均匀分布的随机数数组,浮点数。范围从0到1
t=np.random.rand(3,4)
print(t)

print('*'*50)
# randn(d0,d1...dn) 创建d0~dn维度的标准正态分布随机数,浮点数。平均数0,标准差为1
t1=np.random.randn(3,4)
print(t1)

print('*'*50)
#randint(low,high,(shape)) 从给定上下限范围选区随机数整数。范围是low,high.形状是shape
t2=np.random.randint(10,20,(3,4))
print(t2)

print('*'*50)
# uniform(low,high,(size)) 产生具有均匀分布的数组,low是起始值,high是结束值。size形状
t3=np.random.uniform(1,10,(3,4))
print(t3)

print('*'*50)
# normal(loc,scale,(size)) 从指定正态分布中随机抽取样本,分布中心是loc(概率分布的均值),标准差为scale,形状是size。
t4=np.random.normal(1.0,0.8)
print(t4)

print('*'*50)
# seed(s) 随机数种子,s是给定的种子值,因为计算机生成的是伪随机数,所以设定相同的随机数种子,可以每次生成相同的随机数。
np.random.seed(10)
import numpy as np
# a=b 完全不复制,a和b相互影响
t1=np.arange(10).reshape(2,5)
t2=t1
print(t1)
print(t2)
print('*'*50)
t1[:,[0,1]]=100
print(t1)
print(t2)

# a=b[:] 视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,它们两个的数据变化是一致的。
print('*'*50)
t3=t1[:,1:3]
print(t3)
t3[0,[0,1]]=500
print(t1)
print(t2)
print(t3)

# a=b.copy(),复制,a和b操作互不影响
print('*'*50)
t4=t1.copy()
t4[0,[0,1]]=600
print(t4)
print(t1)

nan和inf

nan(NAN,Nan):not a number表示不是一个数字。

inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷。一个数字除以0,则会出现inf(python中直接会报错,numpy中是一个inf或-inf)

import numpy as np

#False 两个nan是不相等的
print(np.nan==np.nan)

a=np.nan
b=np.inf
print(type(a),type(b)) #<class 'float'> nan,inf的数据类型都是float

t1=np.arange(12).reshape((3,4)).astype(float)
print(t1)
# np.count_nonzero(t)查询数组中非0值的个数
print(np.count_nonzero(t1))


print('*'*50)
t1[2,2:]=np.nan
print(t1)
print(t1[t1!=t1]) # [nan nan] 根据两个nan不相等,则可以查询一个数组中nan值
# np.count_nonezero(t!=t) 判断出数组中nan的个数 或者t!=t 用np.isnan(t)替换 或者上述中len(t1[t1!=t1])获取
print(np.count_nonzero(t1!=t1)) # 2

print('*'*50)
# 修改数组中nan值为0
# 方法一:t1[t1!=t1]=0
#t1[t1!=t1]=0
# 方法二:t1[np.isnan(t1)]=0
t1[np.isnan(t1)]=0
print(t1)
# 总结:t!=t 或np.isnan(t) 结果是一样的

处理数组中的nan值,可以替换为0(不推荐),也可以替换为均值或中值或者直接删除含有nan的一行数据。

import numpy as np

# 将数组中所有列上为nan的值改为平均数
def fill_ndarray(t):
    for i in range(t.shape[1]):
        t_cols = t[:, i]  # 获取数组中列数据
        nan_count = np.count_nonzero(t_cols != t_cols)  # 获取值为nan的元素个数
        if nan_count != 0:
            non_nan_cols = t_cols[t_cols == t_cols]  # 获取除去nan值之外的数据,数组
            t_col_mean = np.mean(non_nan_cols)  # 获取非nan数据的平均值
            t_cols[np.isnan(t_cols)] = t_col_mean # 将值为nan的元素赋值为平均值

if __name__ == '__main__':
    t = np.arange(12).reshape(3, 4).astype('float')
    print(t)
    t[2, :] = np.nan  # 赋值nan
    print(t)
    fill_ndarray(t)
    print(t)

 

 posted on 2024-01-09 21:38  会飞的金鱼  阅读(33)  评论(0)    收藏  举报