python--numpy

废话不多说,直接上代码

import numpy as np

# 如何创建一个数组
arr = np.array([1, 2, 3, 4])
print(arr)  # [1 2 3 4]


# 查看数组的属性
# 数组里元素的总个数
print(arr.size)  # 4


# 数组的形状
print(arr.shape)  # (4,),表示数组只有一个维度,里面有四个元素


# 数组的维度
print(arr.ndim)  # 1


# 数组里元素的类型
print(arr.dtype)  # int32

  

import numpy as np

# 快速构建一个固定值的数组
# 接受的参数为shape。创建的数组值全部为1
arr = np.ones(5)
print(arr)  # [1. 1. 1. 1. 1.]

# 如果想要其他值,只需要乘上相应的数即可
arr1 = np.ones(5) * 8
print(arr1)  # [8. 8. 8. 8. 8.], 这样就得到了元素全为8的数组

# 如果我想获取二维数组怎么办?
arr2 = np.ones((3, 3))  # 还是写上相应的维度,不过这里必须要传入元组。为什么?可以看一下源码,def ones(shape, dtype=None, order='C'):,因此两个维度只能作为一个元组整体传给shape
print(arr2)
'''
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
'''

# 当然除了ones还有一个zeros(相当于np.empty()),功能是一样的,只是元素的值不一样
arr3 = np.zeros(5)
print(arr3)  # [0. 0. 0. 0. 0.]

# 关于拷贝的问题
arr4 = np.zeros(5)
print(arr4)  # [0. 0. 0. 0. 0.]
arr5 = arr4
print(arr5)  # [0. 0. 0. 0. 0.]
# 此时修改了arr4,将arr4中索引为0的元素的值换成10
arr4[0] = 10
# 此时再打印arr5,会发现arr5的值被修改了
print(arr5)  # [10.  0.  0.  0.  0.]
# 原因是arr4,arr5都指向了同一个地址。只要python入门了都能理解,在这里就无须赘述了
# 如何解决,使用copy函数
arr6 = np.zeros(5)
print(arr6)  # [0. 0. 0. 0. 0.]
arr7 = arr6.copy()  # 表示将arr6的值拷贝一份,将arr7指向这个拷贝的值
print(arr7)  # [0. 0. 0. 0. 0.]
# 此时再修改arr6
arr6[0] = 10
# 打印arr7,会发现对arr6的修改没有影响arr7
print(arr7)  # [0. 0. 0. 0. 0.]


# 获取单位矩阵
arr8 = np.eye(5)
print(arr8)
'''
[[1. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 1.]]
'''

  

import numpy as np

# 创建一定数量的随机数组成的数组
# 创建一个元素范围是0到1的数组,里面指定数组的形状,注意这里不需要传入元祖.如果不传参,直接生成一个0到1的一个随机数,和np.random.random()一样
arr1 = np.random.rand(2, 2)
print(arr1)
'''
[[0.64132648 0.35386521]
 [0.5776028  0.19263254]]
'''


# 这个函数,不需要接受参数,只会生成一个随机数,和python的random.random()一样
arr2 = np.random.random()
arr3 = np.random.rand()  # rand里面不传参的话,两者功能是一样的
print(arr2)  # 0.6767998397336757
print(arr3)  # 0.6981771524120665


# 创建指定范围内的一个整数,不包括右边结尾
arr4 = np.random.randint(1, 3)
print(arr4)  # 2
# 如果指定形状的话,一定要以元组的形式
arr5 = np.random.randint(1, 3, (2, 2))  # 表示生成2行2列的数组,数组里面元素为1到3(不包括3)的随机数
print(arr5)
'''
[[1 2]
 [1 1]]
'''


# 创建指定范围的一个随机数,不传参的话,默认是0到1
arr6 = np.random.uniform(1, 3)
print(arr6)  # 1.3521449018009046
# 这里同样可以传入形状
arr7 = np.random.uniform(1, 3, (2, 2))
print(arr7)
'''
[[2.01122666 1.74303599]
 [2.24118912 1.46172109]]
'''


# 关于rand,其实还有一个randn,和rand方法类似,只不过返回的是一个-1到1之间的随机数
arr8 = np.random.randn(2, 2)
print(arr8)
'''
[[ 0.21272592 -0.7284402 ]
 [-1.06310727 -0.91317326]]
'''


# 创建一个正态分布的数组,接受的参数为平均值,标准差(注意不是方差,是标准差),形状
arr9 = np.random.normal(1.5, 0.3, (3, 3))
print(arr9)
'''
[[1.67316405 1.36683971 1.80043196]
 [1.05001658 0.95180213 1.53729273]
 [2.30675779 1.52553859 1.10877468]]
'''


# 表示将0到1切割成10份,组成一个数组。如果没有指定切割的数量,默认切割50份
arr10 = np.linspace(0, 1, 10)
print(arr10)
'''
[0.         0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
 0.66666667 0.77777778 0.88888889 1.        ]
'''

  

import numpy as np

# 获取数组的部分元素,可以通过索引或者切片
# 先生成一个5行5列的数组
arr = np.random.randint(1, 10, (5, 5))
print(arr)
'''
[[7 6 5 5 1]
 [3 4 8 7 8]
 [8 2 1 1 8]
 [2 6 1 2 4]
 [3 8 7 4 9]]
'''


# 通过索引获取某一个元素
# 表示获取第二行,第一个元素。在np.array中是支持这样传值的,当然python的列表是不支持的
# 其实在这里也可以通过arr[1][0]获取值的。如果只是获取单个值的话,是没有问题的。但如果通过切片获取一个子数组的话,是不推荐这样做的,原因下面会解释
value = arr[1, 0]
value1 = arr[1][0]
print(value)  # 3
print(value1)  # 3


# 通过切片获取一个子数组,表示获取第一行第二行,第二列第三列组成的数组
arr1 = arr[1:3, 2: 4]
print(arr)
'''
[[7 6 5 5 1]
 [3 4 8 7 8]
 [8 2 1 1 8]
 [2 6 1 2 4]
 [3 8 7 4 9]]
'''
print(arr1)
'''
[[8 7]
 [1 1]]
'''
# 如果通过arr[1: 3][2: 4]的方式获取的话,表示的是先通过arr[1:3]获取arr的第二行到第三行,然后arr[1:3][2:4]表示在arr的第二行到第三行组成的数组的基础上,再获取第三行到第四行,显然索引越界了


# 改变数组的形状,通过reshape重塑数组的形状
# 由于分割了10分,所以可以组成2行5列,当然我们也可以将5写成-1。如果我们不想计算,只需要指定一个数字,另一个数字写成-1,然后让numpy帮我们计算是多少
arr2 = np.linspace(0, 1, 10).reshape(2, 5)
print(arr2)
'''
[[0.         0.11111111 0.22222222 0.33333333 0.44444444]
 [0.55555556 0.66666667 0.77777778 0.88888889 1.        ]]
'''
# 显然是2的话,那么当我们写入-1,那么numpy很容易计算出是5
arr3 = np.linspace(0, 1, 10).reshape(2, -1)
print(arr3)
'''
[[0.         0.11111111 0.22222222 0.33333333 0.44444444]
 [0.55555556 0.66666667 0.77777778 0.88888889 1.        ]]
'''
# 如果将2改成3的话,会怎么样呢?那么会报错,numpy会发现10除以3除不开
# 会抛出一个ValueError
try:
    np.linspace(0, 1, 10).reshape(3, -1)
except ValueError as e:
    print(e)
'''
cannot reshape array of size 10 into shape (3,newaxis)
'''

  

import numpy as np

# numpy中的计算
# 按条件进行计算
arr = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])

# 如果我想筛选大于50的元素
# arr>50,表示会对数组里的每一个元素执行这个操作,如果满足标记为True,不满足标记为False
print(arr > 50)  # [False False False False False  True  True  True  True  True]
# 将布尔值映射到数组当中,为True的筛选出来,False的不筛选
arr1 = arr[arr > 50]
print(arr1)  # [ 60  70  80  90 100]


# 如果我想筛选大于20并且小于70的元素
# 这里为什么使用一个&,在c语言或者go语言中,出现过&&连接两个条件判断语句
# 注意&&表示两个条件同时成立才成立,而这里的&表示要将两个由True和False组成的数组进行一个位运算。
# 而且,操作符连接的两个数组一定要用括号括起来,否则报错
print(arr[(arr > 20) & (arr < 70)])  # [30 40 50 60]
# 同理,小于20或者大于70,注意不要写两个||
print(arr[(arr < 20) | (arr > 70)])  # [ 10  80  90 100]


# 替换,将大于等于50的替换成60,小于50的替换成40
# np.where接受三个参数,第一个是条件(再次强调,arr>50,不是将数组和50进行比较,而是将数组中的每一个元素和50进行比较),如果条件满足将该元素的值替换成第二个参数对应的值,否则替换成第三个参数对应的值
# np.where具有返回值,返回一个新的数组
arr2 = np.where(arr >= 50, 60, 40)
print(arr2)  # [40 40 40 40 60 60 60 60 60 60]
print(arr)  # [ 10  20  30  40  50  60  70  80  90 100]
# 可以看到arr并没有发生改变


# 求数组的最大值或最小值
arr = np.array([[1, 9], [3, 8], [6, 2], [5, 7], [4, 10]])
print(arr)
'''
[[ 1  9]
 [ 3  8]
 [ 6  2]
 [ 5  7]
 [ 4 10]]
'''


# 在所有元素之间求最大值,或最小值
# 即可以用np.max(arr),也可以使用arr.max(),推荐第一种。一方面是有些功能只能通过np创建,另一方面这样写也比较直观
print(np.max(arr))  # 10
print(np.min(arr))  # 1


# 获取每一行最大值或者最小值
print(np.max(arr, axis=1))  # [ 9  8  6  7 10]
print(np.min(arr, axis=1))  # [1 3 2 5 4]


# 获取每一列的最大值或最小值
print(np.max(arr, axis=0))  # [ 6 10]
print(np.min(arr, axis=0))  # [1 2]


# 获取平均值
print(np.mean(arr))  # 5.5


# 获取方差
print(np.std(arr))  # 2.8722813232690143


# 验证
# 创建一个平均值为4,标准差为1.5, 形状为50行50列的数组
verify_arr = np.random.normal(4, 1.5, (50, 50))
print(np.mean(verify_arr))  # 4.000191219475806
print(np.std(verify_arr))  # 1.4951340773961896


# precentile,接收两个参数
# 参数一:array
# 参数二:0到100的value,表示value%的分位数在arry对应的值
# 这里的50,则表示50%对应的分位数,在array中则正好是中位数,显然25%和75%分别对应左右两个四分位数
print(np.percentile(np.array([1, 2, 30, 40, 50]), 50))  # 30.0
# 五个元素,元素30对应的分位数是50%,元素2对应的分位数25%,那么20%应该比2小
print(np.percentile(np.array([1, 2, 30, 40, 50]), 20))  # 1.8
# 所以看到这里就明白了,np.percentile(array, value)返回一个数值,表示array中value%的元素比返回的数值小,(100-value)%的数值比返回的数值大


# np.irr,表示内部收益率,函数接收一个列表[n,n1,n2,n3,n4,......],返回一个数值r,其中n = n1/(1+r) + n2/(1+r)^2 + n3/(1+r)^3 + ....
# 表示先投了100,然后每个阶段能收回来一部分钱,总共收了五个阶段。收的钱越多,内部收益率越高。
print(np.irr([-100, 10, 10, 40, 50, 40]))  # 0.1195048121414084


# 求矩阵的转置
arr = np.array([[1, 9], [3, 8], [6, 2], [5, 7], [4, 10]])
print(arr)
'''
[[ 1  9]
 [ 3  8]
 [ 6  2]
 [ 5  7]
 [ 4 10]]
'''
print(arr.T)  # 或者np.transpose(arr),不过arr.T更简洁,而且看起来更酷
'''
[[ 1  3  6  5  4]
 [ 9  8  2  7 10]]
'''


# 求矩阵的逆,关于矩阵的逆矩阵,就是和原矩阵相乘(数学上的运算)得到单位矩阵,因此这就意味传入的要是同型矩阵,即矩阵的行数和列数相等
# 当然还有一个函数可以不需要传入同型矩阵
arr = np.array([[1, 9], [3, 8]])
print(arr)
'''
[[1 9]
 [3 8]]
'''
# np.linalg.inv(arr),返回arr的逆矩阵
arr_inv = np.linalg.inv(arr)
print(arr_inv)
'''
[[-0.42105263  0.47368421]
 [ 0.15789474 -0.05263158]]
'''
# 相乘之后得到单位矩阵
print(np.dot(arr, arr_inv))
'''
[[1. 0.]
 [0. 1.]]
'''


# 非同型矩阵
arr = np.array([[1, 9], [3, 8], [6, 2], [5, 7], [4, 10]])
arr_inv = np.linalg.pinv(arr)
print(arr_inv)
'''
[[-0.06784661 -0.00572618  0.13430505  0.05639424 -0.00069408]
 [ 0.05752212  0.02915148 -0.04737116  0.00078084  0.03383654]]
'''
# 相乘之后会变成一个同型矩阵
print(np.dot(arr, arr_inv))
'''
[[ 0.44985251  0.25663717 -0.2920354   0.06342183  0.30383481]
 [ 0.25663717  0.21603332  0.02394586  0.17542946  0.2686101 ]
 [-0.2920354   0.02394586  0.71108798  0.33992712  0.06350859]
 [ 0.06342183  0.17542946  0.33992712  0.2874371   0.23338539]
 [ 0.30383481  0.2686101   0.06350859  0.23338539  0.3355891 ]]
'''

  

import numpy as np

# 数组之间的运算
arr = np.array([1, 2, 3, 4])
arr1 = arr + 2
arr2 = arr - 2
arr3 = arr * 2
arr4 = arr / 2
print(arr1)  # [3 4 5 6]
print(arr2)  # [-1  0  1  2]
print(arr3)  # [2 4 6 8]
print(arr4)  # [0.5 1.  1.5 2. ]
# 再次提示:数组和int进行运算,表示数组当中的每一个值和int进行运算


# 如果是二位数组呢?
print(np.array([[1, 2], [3, 4]]) + 100)
# 依旧对每个元素进行了操作
'''
[[101 102]
 [103 104]]
'''


# 矩阵之间的运算,这里不是简单相乘,而是矩阵之间的运算,所以左矩阵的列数要等于右矩阵的行数。最终运算之后的矩阵的行和列分别和左矩阵的行、右矩阵的列相等
# arr1有三列,所以arr2有三行
arr1 = np.array([[1, 2, 3], [2, 3, 4]])
arr2 = np.array([[1], [2], [3]])
print(np.dot(arr1, arr2))
'''
[[14]
 [20]]
'''


# 矩阵的拼接
arr1 = np.array([[1, 2, 3], [2, 3, 4]])
arr2 = np.array([[3, 4, 5], [4, 5, 6]])
print(arr1)
'''
[[1 2 3]
 [2 3 4]]
'''
print(arr2)
'''
[[3 4 5]
 [4 5 6]]
'''
# 上下拼接,注意要传入元组
print(np.vstack((arr1, arr2)))  # 等价于np.stack((arr1, arr2), axis=0)
'''
[[1 2 3]
 [2 3 4]
 [3 4 5]
 [4 5 6]]
'''
print(np.hstack((arr1, arr2)))  # 等价于np.stack((arr1, arr2), axis=1)
'''
[[1 2 3 3 4 5]
 [2 3 4 4 5 6]]
'''

# 以上暂时就是关于numpy的一些用法,关于numpy还可以读取文件这里就不介绍了,文件读取可以用另一个基于numpy的更强的库--->pandas
# 关于pandas,pandas为python提供了两种数据结构,分别是Series和DataFrame
# 我们知道numpy中的array是一个数组,那么Series相当于给array加上了index。而DataFrame相当于是二维的Series
# 而且一般做数据清洗的时候,都是使用pandas,然后将清洗过的数据交给numpy。然后由numpy去处理,比如作为机器学习的样本等等····

  

猜你喜欢

转载自www.cnblogs.com/traditional/p/9302780.html
今日推荐