Pandas学习记录:第一章 预备知识
一、Python基础
1. 列表推导式与条件赋值
- 列表推导式简化写法: [* for i in *] 。第一个 * 为映射函数,其输入为后面 i 指代的内容,第二个 * 表示迭代的对象。
- 简单总结就是通过for 语句处理表达式里面的变量,如果还要加条件,就加if条件就可以进行条件赋值。
2. 匿名函数与map方法
- 匿名函数就是不需要显式的指定函数名。例如
lambda x: 2*x
- 用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数。
有些函数在代码中只用一次,而且函数体比较简单,使用匿名函数可以减少代码量,看起来比较简洁。
3. zip对象与enumerate方法
- zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
例如
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zipped = zip(a,b)
[(1, 4), (2, 5), (3, 6)]
- enumerate函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,例如
In [22]: L = list('abcd')
In [23]: for index, value in enumerate(L):
....: print(index, value)
....:
0 a
1 b
2 c
3 d
在学习C语言时就一直想实现这个功能,没想到在python里这么简单。
二、Numpy基础
1. np数组的构造
最一般的方法是通过 array 来构造:np.array([1,2,3])
其他特殊数组:
【a】等差序列: np.linspace, np.arange
【b】特殊矩阵: zeros, eye, full
【c】随机矩阵: np.random
关于随机矩阵有一些有意思的地方,choice 可以从给定的列表中,以一定概率和方式抽取结果,就可以用这个函数设计和解决很多概率论的题目。
2. np数组的变形与合并
维度变换: reshape函数感觉很有用,能够帮助用户把原数组按照新的维度重新排列。
In [63]: target = np.arange(8).reshape(2,4)
In [64]: target
Out[64]:
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
In [65]: target.reshape((4,2), order='C') # 按照行读取和填充
Out[65]:
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
In [66]: target.reshape((4,2), order='F') # 按照列读取和填充
Out[66]:
array([[0, 2],
[4, 6],
[1, 3],
[5, 7]])
本来以为按列读取会是‘R’。而是应该是按列读取按行再重新放入,没想到是按列读取按列放入。
3. np数组的切片与索引
布尔索引 np.ix_ 就很直观好用,一看就懂。TRUE的地方拿出来,FALSE的地方丢掉。
4. 常用函数
都很常见,值得注意的是nan*。对于含有缺失值的数组,它们返回的结果也是缺失值,如果需要略过缺失值,必须使用 nan* 类型的函数,统计函数都有对应的 nan* 函数。
5. 广播机制
简单来说就是维度少的数组可以自动拓展到和维数多的数组一样的维度,但也存在一些限制。
6. 向量与矩阵的计算
这部分主要是 向量范数和矩阵范数: np.linalg.norm
ord 参数可选值有点多
三、练习
Ex1:利用列表推导式写矩阵乘法
M1 = np.random.randint(1,10,10).reshape(2,5)
M2 = np.random.randint(1,10,10).reshape(5,2)
print(M1)
print('-' * 5)
print(M2)
M1@M2
>>>
[[6 1 2 8 5]
[6 1 7 9 4]]
-----
[[6 2]
[7 7]
[1 4]
[7 1]
[8 3]]
array([[141, 50],
[145, 68]])
[[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])]
>>>
[[141, 50], [145, 68]]
Ex2:更新矩阵
A = np.arange(1,10).reshape(3,3)
B = A*(1/A).sum(1).reshape(-1,1)
Ex3:卡方统计量
A = np.arange(1, 10).reshape(-1, 3)
B = A.sum(0) * A.sum(1).reshape(-1, 1) / A.sum()
result = ((A - B)**2 / B).sum()
print(result)
'''0.46875'''
Ex4:改进矩阵计算的性能
%time
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)
Ex5:连续整数的最大长度
f = lambda x: np.diff(np.nonzero(np.r_[1, np.diff(x) != 1, 1])).max()
f([1, 2, 5, 6, 7])
f([3, 2, 1, 2, 3, 4, 6])
A = [1, 2, 5, 6, 7]
np.diff(A)
'''array([1, 3, 1, 1])'''
np.diff(A) != 1
'''array([False, True, False, False])'''
np.r_[1, np.diff(A) != 1, 1]
'''array([1, 0, 1, 0, 0, 1])'''
np.nonzero(np.r_[1, np.diff(A) != 1, 1])
'''(array([0, 2, 5]),)'''
np.diff(np.nonzero(np.r_[1, np.diff(A) != 1, 1])).max()
'''
3
'''
还是有点难的,看了答案,还有一些地方没太懂,之后还得再研究研究。
四、总结
学了一些琐碎的知识,看一遍是记不住的,还需要自己多敲一敲。学的都是以前接触的少的,但也不至于太难,对于我这个初学者来说难易适中。做task1的时候事情多,比较忙,以后得多腾出时间多练习。