typora-copy-images-to: Python 数据分析.assets
文章目录
第三章 Python常用数据分析库
3.1 Numpy数值计算
3.1.1 ndarray创建于索引
(1)、创建ndarray对象
① ndarray数据类型
ndarray(数组)是存储单一数据类型的多维数组。
Ndarray比原生Python支持更丰富的数据类型。
注:同一个ndarray中所有元素的类型必须是一致的。
常用的类型有:
bool inti int8 int16 int32 int64
uint8 uint16 uint32 uint64
float16 float32 float64(float)
complex64 complex128(complex)
②ndarray创建
- numpy.array()函数
numpy.array(object, dtype=None, copy=True, order=‘K’,subok=False, ndmin=0)
2) 属性
ndim shape size dtype itemsize
3) 其他创建函数
arange() :创建数值范围并返回 ndarray 对象
numpy.arange(start, stop, step, dtype)
linspace() :创建等差数列
logspace():使用 logspace 函数创建等比数列
zeros() :np.zeros():创建指定大小的数组,数组元素以 0 来填充:
eyes()
ones() :创建指定形状的数组,数组元素以 1 来填充:
diag()
例1:类型转换
# 例3-1
import numpy as np
print('整数42转换为浮点数结果为:', np.float64(42))
print('浮点数42.0转换为整数结果为:', np.int8(42.0))
print('浮点数42转换为布尔型转换结果为:', np.bool(42.0))
print('整数0转换为布尔型结果为:', np.bool(0))
print('布尔型数据True转换为浮点数结果为:', np.float(True))
print('布尔型数据False转换为整型结果为:', np.int8(False))
======================
整数42转换为浮点数结果为: 42.0
浮点数42.0转换为整数结果为: 42
浮点数42转换为布尔型转换结果为: True
整数0转换为布尔型结果为: False
布尔型数据True转换为浮点数结果为: 1.0
布尔型数据False转换为整型结果为: 0
例2:创建数组以及数组的属性
#例3-2
arr1 = np.array([1, 2, 3, 4])
print('创建的一维ndarray为:', arr1)
arr2 = np.array([[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]])
print('创建的二维ndarray为:\n', arr2)
print('ndarray arr2的维数为:', arr2.ndim)
print('ndarray arr2的形状为:', arr2.shape)
print('ndarray arr2的数据类型为:', arr2.dtype)
print('ndarray arr2的元素个数为:', arr2.size)
print('ndarray arr2每个元素的大小为:', arr2.itemsize)
====================================
创建的一维ndarray为: [1 2 3 4]
创建的二维ndarray为:
[[ 1 2 3 4]
[ 4 5 6 7]
[ 7 8 9 10]]
ndarray arr2的维数为: 2
ndarray arr2的形状为: (3, 4)
ndarray arr2的数据类型为: int32
ndarray arr2的元素个数为: 12
ndarray arr2每个元素的大小为: 4
例3:多种方式创建数组:
arange函数创建数组:从0-1,以0.1为间隔
print('使用arange函数创建的ndarray为:', np.arange(0, 1, 0.1))
#使用arange函数创建的ndarray为: [ 0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
linspace函数:numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,
print('使用linspace函数创建的ndarray为:\n',np.linspace(0, 1, 12))
使用linspace函数创建的ndarray为:
[ 0. 0.09090909 0.18181818 0.27272727 0.36363636 0.45454545 0.54545455 0.63636364 0.72727273 0.81818182 0.90909091 1.]
eye函数:
print('使用eye函数创建的ndarray为:\n ', np.eye(3))
使用eye函数创建的ndarray为:
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
diag函数:
print('使用diag函数创建的ndarray为:\n',np.diag([1, 2, 3, 4]))
使用diag函数创建的ndarray为:
[[1 0 0 0]
[0 2 0 0]
[0 0 3 0]
[0 0 0 4]]
ones函数
print('使用ones函数的ndarray为:\n', np.ones((2, 3)))
使用ones函数的ndarray为:
[[ 1. 1. 1.]
[ 1. 1. 1.]]
③ 随机数
Numpy中的random模块提供了随机数功能。常用的函数有:
random() rand() randint()
randn() binomial() normal() beta()
chisquare() gamma() uniform()
seed() permutation() shuffle()
无约束条件下生成随机数:
print('random函数生成的随机数ndarray为:\n', np.random.random(10))
================================
random函数生成的随机数ndarray为:
[ 0.41381415 0.63032933 0.80428808 0.00558091 0.27659344 0.45276289 0.90368923 0.87711742 0.99594568 0.9176871 ]
生成服从均匀分布的随机数:
print('rand函数生成的服从均匀分布的随机数ndarray为:\n', np.random.rand(4, 5))
==================
rand函数生成的服从均匀分布的随机数ndarray为:
[[ 0.62392094 0.12220742 0.25575534 0.59097651 0.36868001]
[ 0.66131018 0.96142126 0.47798724 0.56047269 0.50011493]
[ 0.25033011 0.21701346 0.26519479 0.53479334 0.81102177]
[ 0.9217699 0.2280262 0.5476826 0.3836584 0.24671203]]
生成服从正态分布的随机数:
print('randn函数生成的服从正态分布的随机数ndarray为:\n', np.random.randn(4, 5))
生成给定上下范围的随机数,如创建一个最小值不低于 2、最大值不高于 10 的 2 行 5 列数组:
print('randint函数生成的指定上下限的随机整数ndarray为:\n',
np.random.randint(low=2, high=10, size=[2, 5]))
randint函数生成的指定上下限的随机整数ndarray为:
[[5 6 5 9 8]
[3 3 9 9 3]]
(2)索引与切片
① 一维与list一致
② 多维的每一维度都有一个索引,各个维度的索引之间用逗号隔开。
③ 花式索引
# 代码 3-5
arr = np.arange(10)
print('使用元素位置索引结果为:', arr[5])
print('使用元素位置切片结果为:', arr[3:5])
print('省略单个位置切片结果为:', arr[:5])
print('使用元素反向位置切片结果为:', arr[:-1])
arr[2:4] = 100, 101 # 修改对应下标的值
print('修改后的ndarray arr为:', arr)
print('元素位置等差索引结果为:', arr[1:-1:2])
# 步长为负数时,开始位置必须大于结束位置
print('元素位置负数步长等差索引结果为:', arr[5:1:-2])
======================================
使用元素位置索引结果为: 5
使用元素位置切片结果为: [3 4]
省略单个位置切片结果为: [0 1 2 3 4]
使用元素反向位置切片结果为: [0 1 2 3 4 5 6 7 8]
修改后的ndarray arr为: [ 0 1 100 101 4 5 6 7 8 9]
元素位置等差索引结果为: [ 1 101 5 7]
元素位置负数步长等差索引结果为: [ 5 101]
3.1.2 ndarray的基础操作
(1)变换ndarray的形态
① 设置形状
- 数组名.reshape() #不改变原数组
- 数组名.resize() #改变原数组
- 修改数组的shape属性
- 数据组名.shape=(x,y) #改变原数组
# 代码 3-7
arr = np.arange(12) # 创建一维ndarray
print('创建的一维ndarray arr为:', arr)
arr1 = arr.reshape(3, 4) # 设置ndarray的维度
print('改变形状后的ndarray arr1为:\n', arr1)
print('形状改变后ndarray arr1的维度为:', arr1.ndim)
======================================
创建的一维ndarray arr为: [ 0 1 2 3 4 5 6 7 8 9 10 11]
改变形状后的ndarray arr1为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
形状改变后ndarray arr1的维度为: 2
# 代码 3-7
arr = np.arange(12) # 创建一维ndarray
arr.resize(2, 6)
print('resize改变原ndarray形状,ndarray arr变为:\n', arr)
arr.shape = (4, 3)
print('通过重新设置shape属性后,ndarray arr为:\n', arr)
==============================
resize改变原ndarray形状,ndarray arr变为:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
通过重新设置shape属性后,ndarray arr为:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
是否改变原数组:
reshape不改变原数组:
a1 = np.arange(10)
print('原数组:',a1)
a2 = a1.reshape(2,5)
print('a2:reshape()后的数组:',a2)
print('再次打印原数组:',a1)
=============================
原数组: [0 1 2 3 4 5 6 7 8 9]
a2:reshape()后的数组: [[0 1 2 3 4]
[5 6 7 8 9]]
再次打印原数组: [0 1 2 3 4 5 6 7 8 9]
② 展平ndarray
- 数组名.
ravel()
#展平数组 - 数组名.
flattern()
#展平数组,且可以通过axis参数选择展平方向
# 代码 3-8
arr = np.arange(12).reshape(3, 4)
print('创建的二维ndarray arr为:\n', arr)
print('ndarray arr横向展平后为:', arr.ravel())
==========================================
创建的二维ndarray arr为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
ndarray arr横向展平后为: [ 0 1 2 3 4 5 6 7 8 9 10 11]
# 代码 3-8
print('ndarray arr使用flatten方法横向展平后为:', arr.flatten())
print('ndarray arr使用flatten方法纵向展平后为:', arr.flatten('F'))
========================
ndarray arr使用flatten方法横向展平后为: [ 0 1 2 3 4 5 6 7 8 9 10 11]
ndarray arr使用flatten方法纵向展平后为: [ 0 4 8 1 5 9 2 6 10 3 7 11]
③ 组合ndarray
将多个ndarray组合为一个全新的ndarray
-
numpy.hstack() #横向组合
-
numpy.vstack() #纵向组合
-
numpy.concatenate() #可实现数组的横向和纵向组合,参数axis选择方向
- axis=1:横向组合
- axis=0:纵向组合
-
numpy.dstack() #将一系列ndarray沿纵轴方向进行层叠组合
例1:hstack()、vstack()
# 代码 3-9
arr1 = np.arange(12).reshape(3, 4)
print('创建的ndarray arr1为:\n', arr1)
arr2 = arr1*3
print('创建的ndarray arr2为:\n', arr2)
==================================
创建的ndarray arr1为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
创建的ndarray arr2为:
[[ 0 3 6 9]
[12 15 18 21]
[24 27 30 33]]
===================================
print('hstack横向组合ndarray arr1与arr2为:\n', np.hstack((arr1, arr2)))
===========================
hstack横向组合ndarray arr1与arr2为:
[[ 0 1 2 3 0 3 6 9]
[ 4 5 6 7 12 15 18 21]
[ 8 9 10 11 24 27 30 33]]
================================
print('vstack纵向组合ndarray arr1与arr2为:\n', np.vstack((arr1, arr2)))
==================================
vstack纵向组合ndarray arr1与arr2为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[ 0 3 6 9]
[12 15 18 21]
[24 27 30 33]]
例2:
# 代码 3-9
print('concatenate横向组合arr1与arr2为:\n', np.concatenate((arr1, arr2), axis=1))
print('concatenate纵向组合arr1与arr2为:\n', np.concatenate((arr1, arr2), axis=0))
print('dstack深度组合arr1与arr2为:\n', np.dstack((arr1, arr2)))
========================
concatenate横向组合arr1与arr2为:
[[ 0 1 2 3 0 3 6 9]
[ 4 5 6 7 12 15 18 21]
[ 8 9 10 11 24 27 30 33]]
concatenate纵向组合arr1与arr2为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[ 0 3 6 9]
[12 15 18 21]
[24 27 30 33]]
dstack深度组合arr1与arr2为:
[[[ 0 0]
[ 1 3]
[ 2 6]
[ 3 9]]
[[ 4 12]
[ 5 15]
[ 6 18]
[ 7 21]]
[[ 8 24]
[ 9 27]
[10 30]
[11 33]]]
④ 分割ndarray
numpy.hsplit() #横向分割数组
numpy.vsplit() #纵向分割数组
numpy.split() #可实现横向、纵向分割,axis选择方向
例1:
# 代码 3-10
arr = np.arange(16).reshape(4, 4)
print('创建的二维ndarray arr为:\n', arr)
创建的二维ndarray arr为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
例2:hsplit横向分割
print('hsplit横向分割arr为:\n', np.hsplit(arr, 2))
hsplit横向分割arr为:
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]
),
array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15]])]
例3:vsplit纵向分割
print('vsplit纵向分割arr为:\n', np.vsplit(arr, 2))
vsplit纵向分割arr为:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]),
array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
例4:
print('split横向分割arr为:\n', np.split(arr, 2, axis=1))
print('split纵向分割arr为:\n', np.split(arr, 2, axis=0))
split横向分割arr为:
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]), array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15]])]
split纵向分割arr为:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
(2)排序与搜索
① 排序
- 排序可分为
直接排序
与间接排序
, - 直接排序指对数值直接进行排序;
- 间接排序指根据一个或多个键对数据进行排序。
- sort() 按数值大小排序
- sort函数是最常用的排序方法。 arr.sort()
- sort函数也可以指定一个axis参数,使得sort函数可以沿着指定轴对数据集进行排序。axis=1为沿横轴排序; axis=0为沿纵轴排序。
- argsort() 实现给定一个或多个键时,得到一个由整数构成的索引ndarray, 索引值表示数据在新的顺序下的位置。
- lexsort函数返回值是按照最后一个传入数据排序的。 np.lexsort((a,b,c))
# 代码 3-11
import numpy as np
np.random.seed(42) #设置随机种子
arr = np.random.randint(1, 10, size=12).reshape(4, 3)
print('创建的随机数ndarray arr为:\n', arr)
创建的随机数ndarray arr为:
[[7 4 8]
[5 7 3]
[7 8 5]
[4 8 8]]
print('默认排序后ndarray arr为:\n', np.sort(arr))
print('展平排序的ndarray arr为:', np.sort(arr, axis=None))
默认排序后ndarray arr为:
[[4 7 8]
[3 5 7]
[5 7 8]
[4 8 8]]
展平排序的ndarray arr为: [3 4 4 5 5 7 7 7 8 8 8 8]
sort()横轴排序和纵轴排序:
# 代码 3-11
print('横轴排序后ndarray arr为:\n', np.sort(arr, axis=1))
print('纵轴排序后ndarray arr为:\n', np.sort(arr, axis=0))
横轴排序后ndarray arr为:
[[4 7 8]
[3 5 7]
[5 7 8]
[4 8 8]]
纵轴排序后ndarray arr为:
[[4 4 3]
[5 7 5]
[7 8 8]
[7 8 8]]
argsort() #实现给定一个或多个键时,得到一个由整数构成的索引ndarray,索引值表示数据在新的顺序下的位置。
print('横轴排序后arr的下标为:\n', np.argsort(arr, axis=1))
print('展平排序后arr的下标为:', np.argsort(arr, axis=None))
横轴排序后arr的下标为:
[[1 0 2]
[2 0 1]
[2 0 1]
[0 1 2]]
展平排序后arr的下标为: [ 5 1 9 3 8 0 4 6 2 7 10 11]
② 搜索
- argmax() #求最大元素的索引
- argmin() #求最小元素的索引
- where() #返回数组中满足条件的元素的索引
- extract() #返回数组中满足条件的元素
# 代码 3-12
arr = np.arange(6, 12).reshape(2, 3)
print('创建的ndarray arr为:\n', arr)
print('ndarray arr中最大元素的索引为:', np.argmax(arr))
print('ndarray arr中最小元素的索引为:', np.argmin(arr))
创建的ndarray arr为:
[[ 6 7 8]
[ 9 10 11]]
ndarray arr中最大元素的索引为: 5
ndarray arr中最小元素的索引为: 0
例2:
# 代码 3-12
print('ndarray arr中各列最大元素的索引为:', np.argmax(arr, axis=0))
print('ndarray arr中各行最小元素的索引为:', np.argmin(arr, axis=1))
ndarray arr中各列最大元素的索引为: [1 1 1]
ndarray arr中各行最小元素的索引为: [0 0]
例3:
# 代码 3-13
arr = np.arange(12).reshape(4,3)
print('创建的ndarray arr为:\n', arr)
print('where输出ndarray arr满足条件的下标为:\n', np.where(arr>6))
arr1 = np.arange(12).reshape(3, 4)
print('创建的ndarray arr1为:\n', arr1)
arr2 = np.arange(-12, 0).reshape(3, 4)
print('创建的ndarray arr2为:\n', arr2)
exp = arr1>5
print('arr1大于5的布尔ndarray为:\n', exp)
创建的ndarray arr为:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
where输出ndarray arr满足条件的下标为:
(array([2, 2, 3, 3, 3], dtype=int64), array([1, 2, 0, 1, 2], dtype=int64))
创建的ndarray arr1为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
创建的ndarray arr2为:
[[-12 -11 -10 -9]
[ -8 -7 -6 -5]
[ -4 -3 -2 -1]]
arr1大于5的布尔ndarray为:
[[False False False False]
[False False True True]
[ True True True True]]
例4:
# 代码 3-13
print('where函数搜索符合条件的arr1与arr2为:\n', np.where(exp, arr1, arr2))
arr = np.arange(9).reshape(3, 3)
print('创建的ndarray arr为:\n', arr)
exp = (arr % 2) == 0
print('arr能被2整除的布尔ndarray为:\n', exp)
print('arr基于条件exp提取的元素为:\n', np.extract(exp, arr))
where函数搜索符合条件的arr1与arr2为:
[[-12 -11 -10 -9]
[ -8 -7 6 7]
[ 8 9 10 11]]
创建的ndarray arr为:
[[0 1 2]
[3 4 5]
[6 7 8]]
arr能被2整除的布尔ndarray为:
[[ True False True]
[False True False]
[ True False True]]
arr基于条件exp提取的元素为:
[0 2 4 6 8]
3.1.3 通用函数ufunc(universal function)
通用函数是一种能够对`ndarray中所有元素`进行操作的函数,因此
ndarra能够运用向量化运算
处理整个数组
,完成同样的任务。使用通用函数
比使用math库中的函数效率要高很多。
(1) 常用的ufunc函数运算
包括四则、比较和逻辑运算,和数值运算的使用方式一样,但是操作的
对象是数组。数组间的四则运算表示对每个数组中的元素分别
进行四则运
算,所以进行四则运算的两个数组的形状必须相同。
例1:加法、减法、乘法、幂运算
x=np.array([1,2,3])
y=np.array([4,5,6])
print(x+y)
=========
[5 7 9]
=========
print('x-y:',x-y)
print('x*y:',x*y)
print('x**y:',x**y)
==================
x-y: [-3 -3 -3]
x*y: [ 4 10 18]
x**y: [ 1 32 729]
例2:比较运算
a = np.array([1,3,5])
b = np.array([2,3,6])
print('a<b:',a<b) #a<b: [ True False True]
print('a==b:',a==b) #a==b: [False True False]
(2) 广播机制
广播(Broadcasing)是指不同形状
的数组之间执行算术运算的方式。当参加运算的两个数组的shape不一致时,numpy实现广播机制。
广播机制遵循4个原则:
-
所有的
输入数组
向其中shape最长的数组看齐,shape不足的部分通过在前面加0补齐。
-
输出数组的shape 是输入数组shape各个轴上的最大值
-
如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1,则这个数组能够用来计算,否则出错。
-
当输入数组的某个轴的长度为1时,沿着此轴运算时使用此轴上的第一组值。
#广播机制
arr1 = np.array([[0,0,0],[1,1,1],[2,2,2],[3,3,3]])
print(arr1)
[[0 0 0]
[1 1 1]
[2 2 2]
[3 3 3]]
arr2 = np.array([1,2,3])
arr2
#array([1, 2, 3])
print(arr1+arr2)
[[1 2 3]
[2 3 4]
[3 4 5]
[4 5 6]]
arr3 = np.array([1,2,3,4]).reshape((4,1))
arr3
=========
array([[1],
[2],
[3],
[4]])
print(arr1+arr3)
[[1 1 1]
[3 3 3]
[5 5 5]
[7 7 7]]
(3) 数学运算函数
negative() #求数组中各元素的相反数
exp() #求自然数E 的各元素次幂
absolute() #求数组各元素的绝对值
sqrt() #求各元素的平方根
fabs() #求各元素的绝对值rint() #求各元素最近的整数
sign() #求各元素的符号
log() #求各元素的对数
log2() #求各元素以2为底的对数
log10() #各元素从10为底的对数
curt() #各元素的立方根
reciprocal() #各元素的倒数
conj() #求各元素的共轭复数
例1:
# 代码 3-15
import numpy as np
arr = np.arange(-4, 5).reshape(3, 3)
print('创建的ndarray arr为:\n', arr)
print('ndarray arr各元素的相反数为:\n', np.negative(arr))
print('ndarray arr各元素的绝对值为:\n', np.absolute(arr))
print('ndarray arr各元素的符号为:\n', np.sign(arr))
print('ndarray arr各元素的平方根为:\n', np.sqrt(arr))
print('ndarray arr各元素的自然对数为:\n', np.loglp(arr))
==========================================
创建的ndarray arr为:
[[-4 -3 -2]
[-1 0 1]
[ 2 3 4]]
ndarray arr各元素的相反数为:
[[ 4 3 2]
[ 1 0 -1]
[-2 -3 -4]]
ndarray arr各元素的绝对值为:
[[4 3 2]
[1 0 1]
[2 3 4]]
ndarray arr各元素的符号为:
[[-1 -1 -1]
[-1 0 1]
[ 1 1 1]]
ndarray arr各元素的平方根为:
[[ nan nan nan]
[ nan 0. 1. ]
[ 1.41421356 1.73205081 2. ]]
ndarray arr各元素的自然对数为:
[[ nan nan nan]
[ nan -inf 0. ]
[ 0.69314718 1.09861229 1.38629436]]
(4) 其他函数
- 三角函数 sin()、cos()、tan()。
- 集合运算
unique() #去重并排序 - 比较运算
- 逻辑运算
- 内容测试函数
isnan() #判断数组中的空值
(5) 统计运算函数
可选择轴向,没有轴向则计算出一个值
sum() #元素和
mean() #元素均值
median() #元素中位数
std() #标准差
var() #方差
min() #最小值
max() #最大值
cumsum() #累计和
cumprod() #累计积
# 代码 3-16
arr = np.arange(20).reshape(4, 5)
print('创建的ndarray arr为:\n', arr)
print('ndarray arr各元素的和为:', np.sum(arr))
print('ndarray arr各行的极差为:', np.ptp(arr, axis=1))
print('ndarray arr各列的均值为:', np.mean(arr, axis=0))
print('ndarray arr的中位数为:', np.median(arr))
==========================================
创建的ndarray arr为:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
ndarray arr各元素的和为: 190
ndarray arr各行的极差为: [4 4 4 4]
ndarray arr各列的均值为: [ 7.5 8.5 9.5 10.5 11.5]
ndarray arr的中位数为: 9.5
例2:
# 代码 3-16
print('ndarray arr各行的上四分位数为:',np.percentile(arr, 75, axis =1))
print('ndarray arr各列的下四分位数为:', np.percentile(arr, 25, axis =0))
print('ndarray arr的标准差为:', np.std(arr))
print('ndarray arr的方差为:', np.var(arr))
print('ndarray arr的最小值为:', np.min(arr))
print('ndarray arr的最大值为:', np.max(arr))
=============================================
ndarray arr各行的上四分位数为: [ 3. 8. 13. 18.]
ndarray arr各列的下四分位数为: [ 3.75 4.75 5.75 6.75 7.75]
ndarray arr的标准差为: 5.76628129734
ndarray arr的方差为: 33.25
ndarray arr的最小值为: 0
ndarray arr的最大值为: 19
例3:
# 代码 3-17
arr = np.arange(1, 11)
print('创建的ndarray arr为:', arr)
print('ndarray arr的元素累计和为:', np.cumsum(arr))
print('ndarray arr的元素累计积为:\n', np.cumprod(arr))
========================================================
创建的ndarray arr为: [ 1 2 3 4 5 6 7 8 9 10]
ndarray arr的元素累计和为: [ 1 3 6 10 15 21 28 36 45 55]
ndarray arr的元素累计积为:
[ 1 2 6 24 120 720 5040 40320 362880
3628800]
3.1.4 matrix与线性代数
Numpy中的matrix模块
继承自ndarray的二维对象
,不仅拥有二维
ndarray的属性、方法与函数,还拥有诸多特有的属性与方法。同时matrix
与线性代数
中的矩阵概念几乎完全相同,同样含有转置、共轭和逆矩阵等概念。
矩阵的操作主要有以下几种。
(1) 创建矩阵
numpy.mat()
numpy.matrix()
numpy.bmat() #合并
import numpy as np
mat1 = np.mat("1 2 3 ;4 5 6;7 8 9")
print(mat1)
[[1 2 3]
[4 5 6]
[7 8 9]]
mat2 = np.matrix(([[1,2,3],[4,5,6],[7,8,9]]))
print(mat2)
[[1 2 3]
[4 5 6]
[7 8 9]]
(2) 矩阵的属性和基本运算
① 属性
T 转置
H 返回自身的共轭转置
I 返回自身的逆矩阵
② 基本运算
与ndarray计算类似,能够作用于每个元素。
例1:测试属性
#1)
print('矩阵的转置T:\n',mat1.T)
矩阵的转置T:
[[1 4 7]
[2 5 8]
[3 6 9]]
#2)
print('H 返回自身的共轭转置:\n',mat1.H)
H 返回自身的共轭转置:
[[1 4 7]
[2 5 8]
[3 6 9]]
#3)
print('I 返回自身的逆矩阵:\n',mat1.I)
I 返回自身的逆矩阵:
[[ 3.15251974e+15 -6.30503948e+15 3.15251974e+15]
[ -6.30503948e+15 1.26100790e+16 -6.30503948e+15]
[ 3.15251974e+15 -6.30503948e+15 3.15251974e+15]]
例2:测试基本运算
mat4 = mat1*3
mat4
==========
matrix([[ 3, 6, 9],
[12, 15, 18],
[21, 24, 27]])
(3) 线性代数运算
Numpy
中包含的linalg模块
可提供线性代数所需的功能。
- 主要有:
- dot() #矩阵相乘
- inv() #求逆矩阵
- solve() #求解线性方程组
- eig() #求特征值和特征向量
- eigvals() #求特征值
- svd() #计算奇异值分解
- det() #求行列式
#1)
mat = np.mat('1 2 1;1 2 3;1 3 6')
print(mat)
[[1 2 1]
[1 2 3]
[1 3 6]]
#2)求逆矩阵
inverse = np.linalg.inv(mat)
print('逆矩阵:\n',inverse)
逆矩阵:
[[-1.5 4.5 -2. ]
[ 1.5 -2.5 1. ]
[-0.5 0.5 0. ]]
#3)矩阵相乘
print(np.dot(mat,inverse))
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
print(np.dot(mat,inverse) == np.eye(3))
[[ True True True]
[ True True True]
[ True True True]]
3.1.5 文件读写
Numpy 可以读写磁盘上的文本数据或二进制数据。
NumPy 为 ndarray 对象引入了一个简单的文件格式:npy。
npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。
常用的 IO 函数有:
load()
和save()
函数是读写文件数组数据的两个主要函数,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 .npy 的文件中。savze()
函数用于将多个数组写入文件,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 .npz 的文件中。loadtxt()
和savetxt()
函数处理正常的文本文件(.txt 等)
例1:save()
numpy.save(file, arr, allow_pickle=True, fix_imports=True)
参数说明:
- file:要保存的文件,扩展名为 .npy,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上。
- arr: 要保存的数组
- allow_pickle: 可选,布尔值,允许使用 Python pickles 保存对象数组,Python 中的 pickle 用于在保存到磁盘文件或从磁盘文件读取之前,对对象进行序列化和反序列化。
- fix_imports: 可选,为了方便 Pyhton2 中读取 Python3 保存的数据。
a = np.array([1,2,3,4,5])
# 保存到 outfile.npy 文件上
np.save('D:\python_data\outfile.npy',a)
打开:
可以看出文件是乱码的,因为它们是 Numpy 专用的二进制格式后的数据。
我们可以使用 load() 函数来读取数据就可以正常显示了:
例2:load()
b = np.load('D:\python_data\outfile.npy')
print(b)
================
[1 2 3 4 5]
例3:numpy.savez()
numpy.savez() 函数将多个数组保存到以 npz 为扩展名的文件中。
numpy.savez(file, *args, **kwds)
参数说明:
- file:要保存的文件,扩展名为 .npz,如果文件路径末尾没有扩展名 .npz,该扩展名会被自动加上。
- args: 要保存的数组,可以使用关键字参数为数组起一个名字,非关键字参数传递的数组会自动起名为 arr_0, arr_1, … 。
- kwds: 要保存的数组使用关键字名称。
a = np.array([[1,2,3],[4,5,6]])
b = np.arange(0, 1.0, 0.1)
c = np.sin(b)
# c 使用了关键字参数 sin_array
np.savez("runoob.npz", a, b, sin_array = c)
r = np.load("runoob.npz")
print(r.files) # 查看各个数组名称
print(r["arr_0"]) # 数组 a
print(r["arr_1"]) # 数组 b
print(r["sin_array"]) # 数组 c
['sin_array', 'arr_0', 'arr_1']
[[1 2 3]
[4 5 6]]
[ 0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
[ 0. 0.09983342 0.19866933 0.29552021 0.38941834 0.47942554
0.56464247 0.64421769 0.71735609 0.78332691]
例4:savetxt()、loadtxt()
savetxt() 函数是以简单的文本文件格式存储数据,对应的使用 loadtxt() 函数来获取数据。
np.loadtxt(FILENAME, dtype=int, delimiter=' ')
np.savetxt(FILENAME, a, fmt="%d", delimiter=",")
参数 delimiter 可以指定各种分隔符、针对特定列的转换器函数、需要跳过的行数等。
#1)保存
a = np.array([7,8,9,10])
np.savetxt('D:\python_data\out.txt',a)
#2)加载
b = np.loadtxt('D:\python_data\out.txt')
print(b)#[ 7. 8. 9. 10.]
a=np.arange(0,10,0.5).reshape(4,-1)
np.savetxt("out.txt",a,fmt="%d",delimiter=",") # 改为保存为整数,以逗号分隔
b = np.loadtxt("out.txt",delimiter=",") # load 时也要指定为逗号分隔
print(b)
[[ 0. 0. 1. 1. 2.]
[ 2. 3. 3. 4. 4.]
[ 5. 5. 6. 6. 7.]
[ 7. 8. 8. 9. 9.]]
[ 0. 1. 0.]
[ 0. 0. 1.]]
print(np.dot(mat,inverse) == np.eye(3))
[[ True True True]
[ True True True]
[ True True True]]