Datawhale组队学习(Pandas) task1-预备知识

本文介绍了使用Python的Pandas库进行数据处理的基础知识,包括列表推导式、条件赋值、匿名函数等技巧,以及Numpy库的基础操作,如数组创建、变形、切片、数学运算等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【1】第20期 学习者手册(Pandas)
【2】第一章 预备知识

1. Python 基础

1.1 列表推导式与条件赋值

问题1:生成 [0, 2, 4, 6, 8] 样式的数字序列

  • 写法1:定义函数+循环
def my_func(x):
    return x*2

list = []
for i in range(5):
    list.append(my_func(i))
    
print(list)
  • 写法2:定义函数+列表推导式
list = [my_func(i) for i in range(5)]
print(list)

列表推导式 [* for i in *],第一个 * 表示映射函数,其输入为后面 i 指代的内容,第二个 * 表示迭代的对象。

问题2:用多层嵌套列表推导式生成 ['a_c', 'a_d', 'b_c', 'b_d']

[a+'_'+b for a in ['a', 'b'] for b in ['c', 'd']]

问题3:用带有 if 选择的条件赋值,即value = a if condition else b 实现截断列表中超过5的元素,即超过5的用5代替,小于5的保留原来的值

list = [1, 2, 3, 4, 5, 6, 7]
[i if i<=5 else 5 for i in list]

1.2 匿名函数与map方法

问题4:利用匿名函数生成 [0, 2, 4, 6, 8] 样式的数字序列

[(lambda x:x*2)(i) for i in range(5)]

问题5:利用匿名函数和map函数对匿名函数映射,生成 [0, 2, 4, 6, 8] 样式的数字序列

a = map(lambda x:x*2, range(5))

# 在python2中map()函数返回的是一个列表
# 但是在python3中返回的是一个迭代器(iteration)

for i in a:
    print(i)  # 0 2 4 6 8

list(map(lambda x: 2*x, range(5)))

问题6:利用匿名函数和map函数对匿名函数映射,生成[‘0_a’, ‘1_b’, ‘2_c’, ‘3_d’, ‘4_e’]

# list函数生成列表list('abcd') >>> ['a', 'b', 'c', 'd']
list(map(lambda x,y: str(x)+'_'+y, range(5), list('abcde')))

map() 根据提供的函数对指定序列做映射,语法:map(function, iterable, ...)

注:在做这道题时,总是报错’list’ object is not callable,后来才发现原来是做上面题时我命名了list变量,以后要注意 避免和函数名、方法名和关键词重复。不是第一次犯这种错误了 = =
【3】变量和函数同时使用了list,导致抛出异常

1.3 zip对象与enumerate方法

问题7:用zip打包多个可迭代对象

L1 = list('abcde')
L2 = range(4)

for a, b in zip(L1, L2):
    print(a, b)

# 元素个数与最短的列表一致
>>> 
a 0
b 1
c 2
d 3

问题8:用 enumerate 打包一个可迭代对象并绑定迭代元素的遍历序号

L = list('abcd')
for index, value in enumerate(L):
    print(index, value)

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标。语法:enumerate(sequence, [start=0])sequence 表示一个序列、迭代器或其他支持迭代对象,[start=0] 表示下标起始位置。

问题9:用 zip 压缩 L1L2,并解压

zipped = list(zip(L1, L2))
zipped
>>> [('a', 0), ('b', 1), ('c', 2), ('d', 3)]

list(zip(*zipped))
>>> [('a', 'b', 'c', 'd'), (0, 1, 2, 3)]

问题10:用 zip 建立 L1L2 的字典映射

dict(zip(L1, L2))
>>> {'a': 0, 'b': 1, 'c': 2, 'd': 3}

2. Numpy基础

2.1 np数组的构造

问题11-1:用 array 构造 [1, 2, 3]

np.array([1,2,3])
>>> array([1, 2, 3])

问题11-2:利用 np.linspace, np.arange 构造等差序列

np.linspace(1,5,11) # [起始, 终止], 样本个数
>>> array([1, 2, 3])

np.arange(1,5,2) # [起始, 终止), 步长 
>>> array([1, 3])

问题11-3:构造偏移主对角线1个单位的伪单位矩阵

np.array([1,2,3])
>>> array([1, 2, 3])

问题11-4:利用 np.random 生成随机矩阵

# (1)生成服从0-1均匀分布的三个随机数
np.random.rand(3)
# (2)生成元素服从0-1均匀分布的3*3数组
np.random.rand(3,3)
# (3)生成服从a-b均匀分布的三个随机数
a, b = 5, 15
(b-a) * np.random.rand(3) + a
=======================
# (1)生成服从N(0,1)标准正态分布的三个随机数
np.random.randn(3)
# (2)生成服从方差σ^2, 均值μ一元正态分布的三个随机数
sigma, mu = 2.5, 3
mu + np.random.randn(3) * sigma
=======================
# (1)生成随机整数 [low, high)
low, high, size = 5, 15, (2,2)
np.random.randint(low, high, size)
>>> array([[11,  8],
       [14, 10]])
=======================
# (1)以给定概率取样
my_list = ['a', 'b', 'c', 'd']
np.random.choice(my_list, 2, replace=False, p=[0.1, 0.7, 0.1, 0.1])
>>> array(['c', 'd'], dtype='<U1')
# (2)当不指定概率时则为均匀采样,默认有放回抽样
np.random.choice(my_list, (3,3))
>>> array([['c', 'c', 'c'],
       ['c', 'a', 'd'],
       ['c', 'a', 'c']], dtype='<U1')
=======================
# random.permutation(x) 随机排列一个数组
np.random.permutation(my_list)
>>> array(['d', 'b', 'c', 'a'], dtype='<U1')

arr = np.arange(9).reshape((3,3))
>>> array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
np.random.permutation(arr)
# 如果x是多维数组,则沿其第一个坐标轴的索引随机排列数组
>>> array([[3, 4, 5],
       [6, 7, 8],
       [0, 1, 2]])

2.2 np数组的变形与合并

问题12-1:构造2*3零矩阵,并求转置矩阵

np.zeros((2,3)).T
>>> array([[0., 0.],
       [0., 0.],
       [0., 0.]])

问题12-2:构造两个2*3零矩阵,并分别上下合并、左右合并

# 上下合并
np.r_[np.zeros((2,3)), np.ones((2,3))]
>>> array([[0., 0., 0.],
       [0., 0., 0.],
       [1., 1., 1.],
       [1., 1., 1.]])
# 左右合并
np.c_[np.zeros((2,3)), np.ones((2,3))]
>>> array([[0., 0., 0., 1., 1., 1.],
       [0., 0., 0., 1., 1., 1.]])       
==============
当两个一维数组合并时,均将其看作列向量,然后再进行合并操作
np.array([1,1]) 
>>> array([1, 1])
np.zeros(2) 
>>> array([0., 0.])
np.r_[np.array([1,1]), np.zeros(2)] 
>>> array([1., 1., 0., 0.])
np.c_[np.array([1,1]), np.zeros(2)] 
>>> array([[1., 0.],
           [1., 0.]])
==============
当一维数组和二维数组合并时,将一维数组看作列向量,在长度匹配的情况下只能实现左右合并c_
np.c_[np.array([0,0]), np.ones((2,3))]
>>> array([[0., 1., 1., 1.],
           [0., 1., 1., 1.]])
           
np.r_[np.array([0,0]), np.ones((2,3))]
>>> all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 2 dimension(s)

问题12-3:构造2*4矩阵,(1)并分别使用两种模式填充 转化为4*2矩阵;(2)将原矩阵转化为一维数组

target = np.arange(8).reshape(2,4)
target
>>> array([[0, 1, 2, 3],
       [4, 5, 6, 7]])
target.reshape((4,2), order='C') # 按行读取 按行填充
>>> array([[0, 1, 2, 3],
       [4, 5, 6, 7]])
target.reshape((4,2), order='F') # 按列读取 按列补充
>>> array([[0, 2],
       [4, 6],
       [1, 3],
       [5, 7]])
==============
target.reshape(-1) 
>>> array([0, 1, 2, 3, 4, 5, 6, 7])

2.3 np数组的切片与索引

问题13:构造array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]),并使用布尔索引取值

target = np.arange(9).reshape(3,3)
target
>>> 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

target[np.ix_([True, False, True], [True, False, True])]
>>>
array([[0, 2],
       [6, 8]])
target[np.ix_([1,2], [True, False, True])]
>>>
array([[3, 5],
       [6, 8]])

2.4 常用函数

问题14-1:将[-1,1,-1,0]中大于0的元素保留,小于等于0的元素填充为5

a = np.array([-1, 1, -1, 0])
np.where(a>0, a, 5)
>>> array([5, 1, 5, 5])

问题14-2:取[-2,-5,0,1,3,-1]中非零数的索引、最大值索引、最小值索引

a = np.array([-2,-5,0,1,3,-1])
np.nonzero(a)
>>> (array([0, 1, 3, 4, 5], dtype=int64),)
a.argmax()
>>> 4
a.argmin()
>>> 1

问题14-3:判断[0,1]中是否有非零元素;判断[0,1]中是否全为非零元素

a = np.array([0,1])
a.any()
>>> True
==============
a.all()
>>> False

问题14-4:求[1,2,3]累乘、累加,以及和前一个元素差值

a = np.array([1,2,3])
a.cumprod()
>>> array([1, 2, 6], dtype=int32)

a.cumsum()
>>> array([1, 3, 6], dtype=int32)

np.diff(a)
>>> array([1, 1])

问题14-5:略过[1, 2, np.nan]中缺失值,返回最大值和0.5分位数

target = np.array([1, 2, np.nan])
np.nanmax(target)
>>> 2.0
np.nanquantile(target, 0.5)
>>> 1.5

问题14-6:构造array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])并求行和、列和

target = np.arange(1, 10).reshape(3,-1)
target
>>> array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

# 对行求和
target.sum(0)

>>> array([12, 15, 18])
# 对列求和
target.sum(1)
>>> array([ 6, 15, 24])

【4】Python中axis=0或者axis=1到底该怎么用?

2.5 广播机制

# 标量与数组的操作
np.ones((2,2))
>>> array([[1., 1.],
       [1., 1.]])
3 * np.ones((2,2)) +1
>>> array([[4., 4.],
       [4., 4.]])
==============
# 二维数组之间的操作
# 3*2 与 1*2 逐元素运算----->将1*2扩充至3*2
res = np.ones((3,2))
res * np.array([[2,3]]) # 扩充第一维度为3
>>> array([[2., 3.],
       [2., 3.],
       [2., 3.]])
# 3*2 与 3*1 逐元素运算----->将3*1扩充至3*2
res * np.array([[2],[3],[4]])
>>> array([[2., 2.],
       [3., 3.],
       [4., 4.]])
==============
# 一维数组与二维数组的操作
# 先将(3,)视为(1,3),要与(2,1)逐元素相加----->将(1,3)扩充为(2,3) 将(2,1)扩充为(2,3) 
np.ones(3) + np.ones((2,1))
>>> array([[2., 2., 2.],
       [2., 2., 2.]])

2.6 向量与矩阵的计算

问题15-1:计算[1,2,3][1,3,5]的内积

a = np.array([1,2,3])
b = np.array([1,3,5])
a.dot(b)
>>> 22

问题15-2:计算向量范数和矩阵范数
np.linalg.norm 对应指定 ord 参数即可
在这里插入图片描述

问题15-3:计算array([[0, 1], [2, 3]])array([[-4, -3], [-2, -1]])矩阵乘法

a = np.arange(4).reshape(-1,2)
b = np.arange(-4,0).reshape(-1,2)
a@b
>>> array([[ -2,  -1],
       [-14,  -9]])

3. 练习

3.1 Ex1

在这里插入图片描述

我的思路
在这里插入图片描述

  • 分别取出M1的行、M2的列,相乘,再相加
  • np.array() 转化一下
  • reshape 成结果应有的维度
my_res = np.array([(a*b).sum() for a in M1 for b in M2.T]).reshape(M1.shape[0], M2.shape[1])

答案思路

  • 将三重循环写进列表推导式,先循环 j 把结果的第一行打印出来,再循环 i
  • sum() 套在 k 索引那层循环外,表示映射函数
[[sum([M1[i][k] * M2[k][j] for k in range(M1.shape[1])]) for j in range(M2.shape[1])] for i in range(M1.shape[0])]

3.2 Ex2

在这里插入图片描述
我的思路

# 错误版
a = np.arange(1,10).reshape(3,3)
[[a[i][j] * sum(1/a[i]) for i in range(a.shape[0])] for j in range(a.shape[1])]

>>>
[[1.8333333333333333, 2.466666666666667, 2.6527777777777777],
 [3.6666666666666665, 3.0833333333333335, 3.0317460317460316],
 [5.5, 3.7, 3.4107142857142856]]
# 啊啊啊 居然错了 = = 
# [a[i][j] * sum(1/a[i]) for i in range(a.shape[0])] 这部分不应该单独框起来
np.array([a[i][j] * sum(1/a[i]) for i in range(a.shape[0]) for j in range(a.shape[1])]).reshape(a.shape[0],a.shape[1])
# 这样改就可以了,可是也太麻烦了...

答案思路

  • 取倒数,跨列求和,返回 (3,)
  • 与原矩阵对应元素求乘积,乘积之前记得 reshape 为二维的
A = np.arange(1,10).reshape(3,-1)
B = A*(1/A).sum(1).reshape(-1,1)

# 大佬的代码就是简洁...易懂...

3.3 Ex3

在这里插入图片描述

我的思路

  • 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_{i j}=\frac{\left(\sum_{i=1}^{m} A_{i j}\right) \times\left(\sum_{j=1}^{n} A_{i j}\right)}{\sum_{i=1}^{m} \sum_{j=1}^{n} A_{i j}} Bij=i=1mj=1nAij(i=1mAij)×(j=1nAij) 中的 ( ∑ i = 1 m A i j ) \left(\sum_{i=1}^{m} A_{i j}\right) (i=1mAij) 为跨行求和, ( ∑ j = 1 n A i j ) \left(\sum_{j=1}^{n} A_{i j}\right) (j=1nAij) 为跨列求和
  • 要利用广播对元素相乘,所以对元素 reshape
  • 利用列表推导式求每一项 ( A i j − B i j ) 2 B i j \frac{\left(A_{i j}-B_{i j}\right)^{2}}{B_{i j}} Bij(AijBij)2
  • 对列表中元素求和即为卡方
sum_r = A.sum(axis=0) # 跨行求和
sum_r = sum_r.reshape(1,-1)

sum_c = A.sum(axis=1) # 跨列求和
sum_c = sum_c.reshape(-1,1)

total = A.sum()
B = sum_r * sum_c / total
list_result = [np.square(A[i][j]-B[i][j])/B[i][j] for i in range(A.shape[0]) for j in range(A.shape[1])]
sum(list_result)
>>> 11.842696601945798

答案思路

# 基本思路是一样的,只是我仿佛智障 明明直接可以运算的,我偏用列表推导式挨个循环一下,简直有毒...

A = np.random.randint(10, 20, (8, 5))
B = A.sum(0)*A.sum(1).reshape(-1, 1)/A.sum()
res = ((A-B)**2/B).sum()

3.4 Ex4

在这里插入图片描述
答案思路
答案是将公式拆开,利用广播机制计算
在这里插入图片描述

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

3.5 Ex5

在这里插入图片描述
答案思路
在这里插入图片描述

  • [1,2,5,6,7] 为例,菜鸡如我只能想到用 diff() 计算相邻差值(橘色块),那如何统计差值为 1 的最大连续的个数呢,难住我了…
  • 大佬提供的思路是:找到连续数据的前后两个边界的位置,(下界位置-上界位置)就是连续数据的长度了,最后取max()就能得到最大的连续长度。
  • 那用什么表示边界呢,可以将差值(橘色块),转化为0/1表示(粉色+绿色 首末也要有元素填充),最后通过nonzero()返回边界的索引值,索引值做差就可以表示序列长度了。
# np.r_[1,np.diff(x)!=1,1] 构造0/1边界
# np.nonzero(np.r_[1,np.diff(x)!=1,1]) 返回 1 元素的位置
# np.diff(np.nonzero(np.r_[1,np.diff(x)!=1,1])) 位置做差
f = lambda x:np.diff(np.nonzero(np.r_[1,np.diff(x)!=1,1])).max()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值