datawhale pandas 打卡01 python 基础

这篇博客是datawhale学习活动的笔记,涵盖了Python的基础知识,如for推导式、条件赋值、匿名函数和map映射,以及zip和enumerate的使用。此外,还详细介绍了NumPy的基础,包括数组操作、矩阵运算,以及一系列练习题,旨在提升Python和NumPy的运用能力。
摘要由CSDN通过智能技术生成

这是参加datawhale的学习打卡活动的学习笔记
学习链接:
http://joyfulpandas.datawhale.club/Content/%E5%8F%82%E8%80%83%E7%AD%94%E6%A1%88.html

python基础

for 推导式

在列表中用for语句简单地生成列表

def myfun():
	return '我好帅'
L=[myfun() for i in range(5)]
out: ['我好帅', '我好帅', '我好帅', '我好帅', '我好帅']

if 条件赋值

还在用传统条件判断赋值?直接使用条件赋值

# def myfun(a):
#     if a>0:
#         return 1
#     else:
#         return 0

def myfun(a):
    return 1 if a>0 else 0
myfun(3)
out: 1

匿名函数与map映射

对于简单的,且使用频率低的函数,我们可以直接使用lambda创建匿名函数

fun = lambda x: 2*x
fun(3)
out: 6

当然,一般我们都会直接使用,而不是将匿名函数赋值给一个变量

a =(lambda x: 2*x)(3)
a
out: 6

有了匿名函数,以及map函数,我们就可以用简洁的语法创建一个列表

list(map(lambda x:2*x, range(5)))
out: [0, 2, 4, 6, 8]

zip打包与enumberate

zip打包是将多个可迭代对象打包成一个可迭代的元组

a=[i+1 for i in range(5)]
b=[2*i for i in range(5)]
print(a)
print(b)

for i in zip(a,b):
    print(i)
out: [1, 2, 3, 4, 5]
[0, 2, 4, 6, 8]
(1, 0)
(2, 2)
(3, 4)
(4, 6)
(5, 8)

同时,我们也可以用zip函数快速创建字典

a=[i+1 for i in range(5)]
b=[2*i for i in range(5)]
dict(zip(a,b))
out:{1: 0, 2: 2, 3: 4, 4: 6, 5: 8}

zip方法也提供了解压缩的方法

a=[i+1 for i in range(5)]
b=[2*i for i in range(5)]
print(f'a:{a}')
print(f'b:{b}')
c=list(zip(a,b))
d,e=list(zip(*c))
print(f'd:{d}')
print(f'e:{e}')

out: a:[1, 2, 3, 4, 5]
b:[0, 2, 4, 6, 8]
d:(1, 2, 3, 4, 5)
e:(0, 2, 4, 6, 8)

out:{1: 0, 2: 2, 3: 4, 4: 6, 5: 8}

在迭代时,我们常用另一个打包方法enumberate,它是一个特殊的打包函数

L = list('abcd')
for index, value in enumerate(L):
     print(index, value)
out:0 a
1 b
2 c
3 d

numpy基础

数组创建和操作

创建向量常用函数功能
linspace等差数列,起始、终止(包含)、样本个数
arange等差数列,起始、终止(不包含)、步长
ones创建全为1的向量
zeros创建全为0的向量
创建矩阵常用函数功能
eye创建单位阵
empty创建空矩阵,申请空间但是不赋值
full用某个数填满矩阵
print(np.linspace(1,10,5))
# [ 1.    3.25  5.5   7.75 10.  ]
print(np.arange(1,10,2))
# [1 3 5 7 9]
print(np.eye(3,4,-1))
'''
[[0. 0. 0. 0.]
 [1. 0. 0. 0.]
 [0. 1. 0. 0.]]
'''
print(np.ones(5))
# [1. 1. 1. 1. 1.]
print(np.zeros(5))
# [0. 0. 0. 0. 0.]
print(np.full((3,4),5))
'''
[[5 5 5 5]
 [5 5 5 5]
 [5 5 5 5]]
'''

数组变形与合并

用到的方法:

方法作用
.T转置
r_水平拼接
c_垂直拼接
reshape修改矩阵形状

需要特别注意reshape函数的一个参数order,它被用来控制填充的顺序
C是按照行读取和填充,F是按照列读取和填充

a=np.arange(8).reshape(2,4)
print(a)
print(a.reshape(4,2,order='C'))# 按照行读取和填充
'''
[[0 1]
 [2 3]
 [4 5]
 [6 7]]
'''
print(a.reshape(4,2,order='F'))# 按照列读取和填充
'''
[[0 2]
 [4 6]
 [1 3]
 [5 7]]
'''

数组切片与索引

像python自带的列表一样,numpy的数组也可以继续切片或者索引操作。

a=np.arange(9).reshape(3,-1)

print(a[:,1])
# [1 4 7]
print(a[2,:])
# [6 7 8]
print(a[:,[0,2]])
'''
[[0 2]
 [3 5]
 [6 8]]
'''

常用函数

函数名函数作用
where条件函数,可以指定满足条件与不满足条件位置对应的填充值
nonzero, argmax, argmin这三个函数返回的都是索引,nonzero返回非零数的索引,argmax, argmin分别返回最大和最小数的索引
anyany指当序列至少 存在一个 True或非零元素时返回True,否则返回False,
allall指当序列元素 全为 True或非零元素时返回True,否则返回False
cumprod累乘
cumsum累加
diff表示和前一个元素做差,由于第一个元素为缺失值,因此在默认参数情况下,返回长度是原数组减1
max, min, mean, median, std, var, sum, quantile分别表示最大值,最小值,平均值,中位数,标准差,方差,求和,分位数,如果数据中有nan,可以在统计函数前面加nan来排除nan

矩阵运算

方法作用
dot计算向量的内积
np.linalg.norm计算范数,通过ord参数计算不同的范数
@矩阵乘法

ord参数具体如下

ordnorm for matricesnorm for vectors
NoneFrobenius norm2-norm
‘fro’Frobenius norm F-范数/
‘nuc’nuclear norm/
infmax(sum(abs(x), axis=1))max(abs(x))
-infmin(sum(abs(x), axis=1))min(abs(x))
0/sum(x != 0)
1max(sum(abs(x), axis=0))as below
-1min(sum(abs(x), axis=0))as below
22-norm (largest sing. value) 最大奇异值as below
-2smallest singular value 最小奇异值as below
other/sum(abs(x)**ord)**(1./ord)

练习题

Ex1:利用列表推导式写矩阵乘法¶

一般的矩阵乘法根据公式,可以由三重循环写出,请将其改写为列表推导式的形式。
在这里插入图片描述

答案:

import numpy as np
M1 = np.random.rand(2,3)
M2 = np.random.rand(3,4)

print(M1)
print(M2)
# 取向量 取数 求和
res=np.array([[np.sum([i*j for i,j in zip(a,b)]) for b in M2.T]for a in M1])
(np.abs((M1@M2-res)<1e-15)).all()

外层循环是第一个向量的行,内层循环是第二个向量转置的行,再利用求和求解最终的结果

Ex2:更新矩阵

在这里插入图片描述
由于每一行的元素乘的系数都一样,考虑将其存储在一个数组中,观察系数,是由A中元素全部取倒数,然后对行进行求和得到的。最终只需要将原矩阵乘上相应的系数就好了

import numpy as np
a=np.arange(9).reshape(3,3)+1
c=np.array([np.sum(1/a,axis=1)]).T
b=a*c
b

Ex3:卡方统计量

设矩阵 A m × n A_{m\times n} Am×n,记 B i j = ( ∑ i = 1 m A i j ) × ( ∑ j = 1 n A i j ) ∑ i = 1 m ∑ j = 1 n A i j B_{ij} = \frac{(\sum_{i=1}^mA_{ij})\times (\sum_{j=1}^nA_{ij})}{\sum_{i=1}^m\sum_{j=1}^nA_{ij}} Bij=i=1mj=1nAij(i=1mAij)×(j=1nAij),定义卡方值如下:
χ 2 = ∑ i = 1 m ∑ j = 1 n ( A i j − B i j ) 2 B i j \chi^2 = \sum_{i=1}^m\sum_{j=1}^n\frac{(A_{ij}-B_{ij})^2}{B_{ij}} χ2=i=1mj=1nBij(AijBij)2

在这里插入图片描述
和矩阵乘法类似,注意迭代顺序,将行作为外层循环,列作为内层循环,得到B矩阵。
有了B矩阵,计算卡方统计量就变得非常简单了,只需要将A,B看成一个整体去计算就好
答案:

sum_A=np.sum(A)
B=np.array([[np.sum(A[j,:])*np.sum(A[:,i])/sum_A for i in range(A.shape[1])] for j in range(A.shape[0])])
res=(B-A)**2/B
res

Ex4:改进矩阵计算的性能

Z Z Z m × n m×n m×n的矩阵, B B B U U U分别是 m × p m×p m×p p × n p×n p×n的矩阵, B i B_i Bi B B B的第 i i i行, U j U_j Uj U U U的第 j j j列,下面定义 R = ∑ i = 1 m ∑ j = 1 n ∥ B i − U j ∥ 2 2 Z i j \displaystyle R=\sum_{i=1}^m\sum_{j=1}^n\|B_i-U_j\|_2^2Z_{ij} R=i=1mj=1nBiUj22Zij,其中 ∥ a ∥ 2 2 \|\mathbf{a}\|_2^2 a22表示向量 a a a的分量平方和 ∑ i a i 2 \sum_i a_i^2 iai2

现有某人根据如下给定的样例数据计算 𝑅 的值,请充分利用Numpy中的函数,基于此问题改进这段代码的性能。

np.random.seed(0)
m, n, p = 100, 80, 50
B = np.random.randint(0, 2, (m, p))
U = np.random.randint(0, 2, (p, n))
Z = np.random.randint(0, 2, (m, n))
def solution(B=B, U=U, Z=Z):
    L_res = []
    for i in range(m):
        for j in range(n):
            norm_value = ((B[i]-U[:,j])**2).sum()
            L_res.append(norm_value*Z[i][j])
    return sum(L_res)
solution(B, U, Z)

答案:

(((B**2).sum(1).reshape(-1,1) + (U**2).sum(0) - 2*B@U)*Z).sum()

Ex5:连续整数的最大长度

输入一个整数的Numpy数组,返回其中严格递增连续整数子数组的最大长度,正向是指递增方向。例如,输入[1,2,5,6,7],[5,6,7]为具有最大长度的连续整数子数组,因此输出3;输入[3,2,1,2,3,4,6],[1,2,3,4]为具有最大长度的连续整数子数组,因此输出4。请充分利用Numpy的内置函数完成。(提示:考虑使用nonzero, diff函数)

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

f = lambda x:np.diff(np.nonzero(np.r_[1,np.diff(x)!=1,1])).max()
f([0,1,2,5,6])
f([-5,-4,-3,-2,-1,0])
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值