python科学计算的例子_Python科学计算:NumPy

NumPy 数组结构和 Python 列表 list 对比:

标准的 Python 中,用列表 list 保存数组的数值。由于列表中的元素可以是任意的对象,所以列表中list保存的是对象的指针。虽然在 Python 编程中隐去了指针的概念,但是数组有指针,Python 的列表 list 其实就是数组。这样如果我要保存一个简单的数组 [0,1,2],就需要有 3 个指针和 3 个整数的对象,这样对于 Python 来说是非常不经济的,浪费了内存和计算时间。

列表 list 的元素在系统内存中是分散存储的,而 NumPy 数组存储在一个均匀连续的内存块中。这样数组计算遍历所有的元素,不像列表 list 还需要对内存地址进行查找,从而节省了计算资源。另外在内存访问模式中,缓存会直接把字节块从 RAM 加载到CPU 寄存器中。因为数据连续的存储在内存中,NumPy 直接利用现代 CPU 的矢量化指令计算,加载寄存器中的多个连续浮点数。另外 NumPy 中的矩阵计算可以采用多线程的方式,充分利用多核 CPU 计算资源,大大提升了计算效率。

当然除了使用 NumPy 外,你还需要一些技巧来提升内存和提高计算资源的利用率。一个重要的规则就是:避免采用隐式拷贝,而是采用就地操作的方式。举个例子,如果我想让一个数值 x 是原来的两倍,可以直接写成 x*=2,而不要写成 y=x*2。

ndarray对象:

创建数组:

import numpy as np

a = np.array([1, 2, 3])

b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

b[1,1]=10

print(a.shape)

print(b.shape)

print(a.dtype)

print(b)

# 运行结果:

(3,)

(3, 3)

int32

[[ 1 2 3]

[ 4 10 6]

[ 7 8 9]]

结构数组:

import numpy as np

persontype = np.dtype({

'names':['name', 'age', 'chinese', 'math', 'english'],

'formats':['S32','i', 'i', 'i', 'f']})

peoples = np.array([("ZhangFei",32,75,100, 90),("GuanYu",24,85,96,88.5),

("ZhaoYun",28,85,92,96.5),("HuangZhong",29,65,85,100)],

dtype=persontype)

ages = peoples['age']

chineses = peoples['chinese']

maths = peoples['math']

englishs = peoples['english']

print(np.mean(ages))

print(np.mean(chineses))

print(np.mean(maths))

print(np.mean(englishs))

# 运行结果

28.25

77.5

93.25

93.75

答疑 :定义结构数组中的 S32 代表什么意思?

这里实际上用的是 numpy 中的字符编码来表示数据类型的定义,比如 i 代表整数,f 代表单精度浮点数,S 代表字符串,S32 代表的是 32 个字符的字符串。

# 如果数据中使用了中文,可以把类型设置为 U32,比如:

import numpy as np

persontype = np.dtype({

'names':['name', 'age', 'chinese', 'math', 'english'],

'formats':['U32','i', 'i', 'i', 'f']})

peoples = np.array([(" 张飞 ",32,75,100, 90),(" 关羽 ",24,85,96,88.5), (" 赵云 ",28,85,92,96.5),(" 黄忠 ",29,65,85,100)], dtype=persontype)

ufunc运算:

连续数组的创建:

x1 = np.arange(1,11,2) # 初始值、终值、步长

x2 = np.linspace(1,9,5) # 初始值、终值、元素个数

算数运算:

x1 = np.arange(1,11,2)

x2 = np.linspace(1,9,5)

print(np.add(x1, x2)) # 加

print(np.subtract(x1, x2)) # 减

print(np.multiply(x1, x2)) # 乘

print(np.divide(x1, x2)) # 除

print(np.power(x1, x2)) # 幂

print(np.remainder(x1, x2)) # 取余

# 运行结果:

[ 2. 6. 10. 14. 18.]

[0. 0. 0. 0. 0.]

[ 1. 9. 25. 49. 81.]

[1. 1. 1. 1. 1.]

[1.00000000e+00 2.70000000e+01 3.12500000e+03 8.23543000e+05

3.87420489e+08]

[0. 0. 0. 0. 0.]

统计函数:

import numpy as np

a = np.array([[1,2,3], [4,5,6], [7,8,9]])

print(np.min(a)) # 全部元素的最小值

print(np.min(a,0)) # 竖轴方向的最小值

print(np.min(a,1)) # 横轴方向的最小值

print(np.max(a))

print(np.max(a,0))

print(np.max(a,1))

# 运行结果:

1

[1 2 3]

[1 4 7]

9

[7 8 9]

[3 6 9]

数组中最大值与最小值的差:

a = np.array([[1,2,3], [4,5,6], [7,8,9]])

print(np.ptp(a)) # 全部元素最大值和最小值的差

print(np.ptp(a,0)) # 竖轴方向最大值和最小值的差

print(np.ptp(a,1)) # 横轴方向最大值和最小值的差

# 运行结果:

8

[6 6 6]

[2 2 2]

统计数组的百分位数 percentile()

a = np.array([[1,2,3], [4,5,6], [7,8,9]])

print(np.percentile(a, 50)) # 所有元素中第50%位元素

print(np.percentile(a, 50, axis=0)) # 竖轴方向第50%位元素

print(np.percentile(a, 50, axis=1)) # 横轴方向第50%位元素

# 输出结果:

5.0

[4. 5. 6.]

[2. 5. 8.]

统计数组中的加权平均值 average()

a = np.array([1,2,3,4])

wts = np.array([1,2,3,4])

print(np.average(a))

print(np.average(a,weights=wts))

# 输出结果:

2.5

3.0

加权平均的意思就是每个元素可以设置个权重,默认情况下每个元素的权重是相同的,所以 np.average(a)=(1+2+3+4)/4=2.5,

你也可以指定权重数组 wts=[1,2,3,4],这样加权平均 np.average(a,weights=wts)=(1*1+2*2+3*3+4*4)/(1+2+3+4)=3.0

统计数组中的标准差 std()、方差 var()

a = np.array([1,2,3,4])

print(np.std(a))

print(np.var(a))

# 输出结果:

1.118033988749895

1.25

方差的计算是指每个数值与平均值之差的平方求和的平均值,标准差是方差的算术平方根。在数学意义上,代表的是一组数据离平均值的分散程度。

NumPy 排序

a = np.array([[4,3,2],[2,4,1]])

print(np.sort(a)) # 默认横轴方向升序

print(np.sort(a, axis=None)) # 降维+升序

print(np.sort(a, axis=0)) # 竖轴方向升序

print(np.sort(a, axis=1)) # 横轴方向升序

# 运行结果:

[[2 3 4]

[1 2 4]]

[1 2 2 3 4 4]

[[2 3 1]

[4 4 2]]

[[2 3 4]

[1 2 4]]

sort(a, axis=-1, kind=‘quicksort’, order=None),默认情况下使用的是快速排序;在 kind 里,可以指定quicksort、mergesort、heapsort

分别表示快速排序、合并排序、堆排序。同样 axis 默认是 -1,即沿着数组的最后一个轴进行排序,也可以取不同的 axis 轴,或者 axis=None

代表采用扁平化的方式作为一个向量进行排序。另外 order 字段,对于结构化的数组可以指定按照某个字段进行排序。

练习题:

假设一个团队里有 5 名学员,成绩如下表所示。你可以用 NumPy 统计下这些人在语文、英语、数学中的平均成绩、最小成绩、最大成绩、方差、标准差。然后把这些人的总成绩排序,得出名次进行成绩输出。

persontype = np.dtype({

'names':['name', 'chinese','english','math' ],

'formats':['S32', 'i', 'i', 'i']})

peoples = np.array([("ZhangFei",66,65,30),("GuanYu",95,85,98),

("ZhaoYun",93,92,96),("HuangZhong",90,88,77),

("DianWei",80,90,90)],dtype=persontype)

name = peoples['name']

chinese = peoples['chinese']

english = peoples['english']

math = peoples['math']

#定义函数用于显示每一排的内容

def show(name,cj):

print('{} | {} | {} | {} | {} | {} '

.format(name,np.mean(cj),np.min(cj),np.max(cj),np.var(cj),np.std(cj)))

print("科目 | 平均成绩 | 最小成绩 | 最大成绩 | 方差 | 标准差")

show("语文", chinese)

show("英语", english)

show("数学", math)

print("排名:")

ranking = sorted(peoples,key=lambda x:x[1]+x[2]+x[3])

print(ranking) # 默认升序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值