以下纯属个人理解随意记录,肯定有不足之处,若有朋友发现错误和理解分歧之处,欢迎一起分享讨论,共同进步! 谢谢( ̄▽ ̄)~*
后续会继续更新 ( ̄▽ ̄)~*
Python 阶段一
1.Python中的数据类型(整型,字符串,元组,集合,列表,字典),
可变类型(集合,列表,字典)
不可变类型(整型,字符串,元组)
2.Python中连续赋值在python中是允许的.如 x= y=z=1
3.可变类型不可作为字典的key
4.字符串的方法 split 的使用,split(‘分割符’,次数)返回列表结果
5.字符串的截取与拼接,截取的时候也是取头去尾的
6.True在参与运算的时候为1,False参与运算的时候为0
7.random.random()的取值范围是[0,1),random是随机取值 (# 和random.rand一样)
random.uniform(a, b),用于生成一个指定范围内的随机**符点数**(包括a,b)
random.randint(a, b),用于生成一个指定范围内的整数(包括a,b)
random.choice从序列中获取一个随机元素。其函数原型为:random.choice(sequence)
list, tuple, 字符串都属于sequence
random.sample的函数原型为:random.sample(sequence, k),从指定序列中随机获取指定长度的片断. 例如:
list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
slice = random.sample(list, 5) #从list中随机获取5个元素,作为一个片断返回
print slice
8.“+”这个符号不能用于集合,(集合具有去重功能,)
9.集合set 运算 “交集( &),并集( | ),差集( - ),对称差集( ^ ), 包含与被包含( > 与 <)”
-
函数参数 *args 接收的是一个元组(位置参数,即 单个的值)
**kwargs 接收的是一个字典(关键字参数,即成对的,如a = 1 ==> a : 1)
11.函数的变量:
global关键字用在函数中修改全局变量
nonlocal也是用在函数中修改函数作用域内的局部变量
locals( )可以查看所有函数内部的局部变量
- self的意义:
self 不是一个关键字,只是一个形参;
self是指向当前的类,谁调用就指向谁
self可以用来引用类中其他属性,调用类中其他方法
13.类方法、静态方法和对象方法的区别:
1)对象方法 a.怎么声明: 直接声明在类中的函数 b.怎么调用: 通过对象来调用 c.特点: 有个指向当前对象的默认参数self;调用的时候不需要传参 d.什么时候用: 实现函数的功能需要用到对象属性
2)类方法 a.怎么声明: 声明函数前加'@classmethod' b.怎么调用: 通过类来调用, '类.方法名()' c.特点: 有个默认参数cls, 这个参数在通过类调用的时候不需要传参; 指向当前类(谁调用指向谁) 类能做的事情,cls都可以做 d.什么时候用: 实现函数的功能不需要对象属性的前提下,需要类的字段(需要类),这个时候就用类方法
3)静态方法 a.怎么声明: 声明函数前加'@staticmethod' b.怎么调用: 通过类来调用, '类.方法名()' c.特点: 没有特点(没有默认参数) d.什么时候用:实现函数的功能既不需要对象属性也不需要类的字段,这个时候就使用静态方法
- 类属性和对象属性的区别
类属性在类中是共享的,对象属性是独立的,不会相互干扰
类属性可以使用类和对象进行调用,
而对象属性只能通过对象属性进行调用
- 九九乘法表
for i in range(1,10):
for j in range(1,i+1):
print(f"{j} * {i} = {i*j}",end="")
print()
- 冒泡排序
nums = [1,2,4,6,3,5,4,4,9,1]
for i in range(len(nums)-1):
for j in range(len(nums)-1-i):
if nums[j] > nums[j+1]:
nums[j],nums[j+1] = nums[j+1],nums[j]
print(nums)
17.选择排序
nums = [9,7,6,8,5,4,3,2,1]
# 方法一:
for i in range(len(nums)-1):
min_index = i
for j in range(i, len(nums)):
if nums[j] < nums[min_index]:
min_index = j
# 用最小数和第i个元素交换
nums[i], nums[min_index] = nums[min_index], nums[i]
print(nums)
# 方法二:
for i in range(0,len(l)-1):
for j in range(i+1,len(l)):
if l[i]>l[j]:
l[i],l[j] = l[j],l[i]
print(l)
# 方法三:利用np.argmin求出最小值的下标,然后进行交换
l = np.array([1,3,5,7,9,2,4,6,8])
for i in range(0,len(l)-1):
index = np.argmin(l[i: ]) + i
l[index],l[i] = l[i],l[index]
print(l)
18.插入排序(逆序比较)
l = [3, 1, 5, 7, 9, 2, 4, 6, 8]
for i in range(1,len(l)):
for j in range(i,0,-1):
if l[j] < l[j-1]:
l[j],l[j-1] = l[j-1],l[j]
print(l)
19.快速排序(使用递归, 引入两个游标low, high ,三个参数 L, start, end)
# 方法一:
def quick_sort(l, start, end):
if start >= end:
return
low = start
high = end
mid = l[start]
while low < high:
while low < high and l[high] > mid:
high -= 1
l[low] = l[high]
while low < high and l[low] < mid:
low += 1
l[high] = l[low]
l[low] = mid
quick_sort(l, start, low - 1)
quick_sort(l, low + 1, end)
l = [9, 7, 5, 3, 1, 8, 6, 4, 2]
quick_sort(l, 0, len(l) - 1)
print(l)
# 方法二:
def quick_sort(l):
# 递归退出的条件
length = len(l)
if length <= 1:
return l
else:
# 可以选第一个元素作为基准值,也可以选最后一个
value = l.pop()
greater, lesser = [], []
for element in l:
if element > value:
greater.append(element)
else:
lesser.append(element)
return quick_sort(lesser) + [value] + quick_sort(greater)
Mysql
- MySQL数据库相关操作:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L5wyNagO-1602840501516)(C:\Users\qf\Desktop\微信截图_20200813170237.png)]
1.多表查询
1.表与表之间的关系
2.合并结果集 (union 去重/ union all 所有)
3.连接查询
1) 内连接: join....on 条件;
2) 外连接: left join...on / right join...on
4.子查询: select语句中嵌套 select.
Numpy Pandas(Jupyter notebook)
numpy
1,ndarray创建的三种方式:
- np.array(列表)
- np.arange()
2.将一个ndarray所有元素位置反转(和列表一样) ==> n[ : : -1]
3.np中函数partition可以求出一维数组中前n大/前n小的数,不需要排序完所有的数.
排序还有np.sort()
n = np.random.randint(10,size=(10,)) 参数size用来调整ndarray是几维数组
x = np.partition(n,kth =-1) kth的正负表示前n大/前n小
y = np.partition(n,kth =+1)
4.np.zeros() / np.ones()中调整是维数的参数是shape=(,) ,其他ndarray调整维数是size=(,)
5.np.argmin() ==>表示最小值索引(下标)
np.argmax() ==>表示最大值索引(下标)
np.argsort(切片某列) ==>表示按照多维数组某列数值排序后索引
例如: sort_index = np.argsort(n[:,2])
6.给定一个4维矩阵,求得到最后两维的和.
n = np.random.randint(10,size = (2,3,4,5)) # size中从左至右维数由高到低 ,即 4-3-2-1维
n.sum(axis = (2,3)) # size中从左至右维数由高到低 , 哪几维的求和参数 axis = (哪几维)
7.给定一个二维矩阵,如何交换其中两行(或多行)的元素.
n = np.random.randint(10,size=(3,4))
n[ [2,0,1] ] # 索引变换即可
8.ndarray 和 dataframe聚合时(sum , mean…)
参数 axis = 0表示对行聚合(可以理解为锯掉行保留一列即对列求和或求平均)
参数 axis = 1表示对列聚合(可以理解为锯掉列保留一行即对行求和或求平均)
mean = n.mean(axis = 1)
sum = n.sum(axis = 0)
9.创建如下8*8矩阵
pandas
一维:series
二维:dataframe
三维:multindex 或者叫做 panel
1.series : 类似于一维数组的对象,可看做是一个定长的有序字典 (values ; index)
2.DataFrame是一个表格型的数据结构,可以看做是由Series组成的字典(共用同一个索引)
行索引( index ) / 列索引( columns) ; values(numpy的二维数组)
3.DataFrame的创建 : 常用方法是传递一个字典的来创建
字典的key 作为每一列的名称即列索引, 字典的value( 一个数组 )作为每一列数据
同Series一样,若传入的列与字典的建不匹配,则相应的值为NaN
-
DataFrame中,直接使用中括号"[ ]"时, 索引表示的是列索引 , 切片表示的是行切片
-
行 / 列索引不存在时,则会新增一行/ 一列,可以赋值作为表格的新增数据
-
取元素时遵循 先行后列原则
-
-
None 与np.nan 的区别?
None 是Python自带的,其类型为Python object, 不能参加任何计算
np.nan是浮点类型,可以参与计算,但是计算的结果总是NaN
-
Pandas中的None与np.nan 都视为np.nan,在表格中都显示为NaN
7.df中缺失值的处理{ isnull( ).any() ; notnull( ).all( ) }
-
df. isnull( ).any (默认axis = 0 ,可指定行或列) : 只要存在一个NaN值,就返回True
-
df. notnull( ).all (默认axis = 0 ,可指定行或列) : 整行或者整列都为NaN值,就返回True
-
df. notnull( ).all( ) <==> 非df. isnull( ).any( )
-
在多级索引的DataFrame中,切片尽量使用 隐式切片
-
填充函数 fillna( );关于参数axis
上 ==> 前行 ==> axis=0 表示 “行”
下 ==> 后行 ==> axis=0 表示 “行”
左 ==> 前列 ==> axis=1 表示 “列”
右 ==> 后列 ==> axis=1 表示 “列”
-
axis = 0 跨行( 垂直向下) 计算行索引
axis = 1 跨列( 水平延伸) 计算列索引
-
10.pandas中DateFrame中查询某符合条件的列数据并修改整列数据
# 例如:
# temp是一个DateFrame,
temp.loc[temp['state/region'] == 'USA'] # 也是一个DateFrame
# temp.loc[temp['state/region'] == 'USA', 'state']
# 上一行表示'state'这一列数据,下一行表示都修改为'United State of America'
temp.loc[temp['state/region'] == 'USA', 'state'] = 'United State of America'
11.pandas新增列的四种方法:
-
直接赋值法( df.loc[ : ,“新增列名”]= )
-
df.apply ( df.loc[ : ,“新增列名”]= df.apply(定义的函数名 , axis= 1) )
-
df.assign { df.assign( 新增列名1 = 定义的函数名 , 新增列名1 = 定义的函数名 … ) } # 利用了字典的方式可以新增多列
-
按条件选择分组分别赋值
新增一列空值 df[‘列名’] = ’ ’
df.loc[ 条件表达式 ,“新增列名”] = “结果”
12.astype 转换类型
# 可以将df中没有缺失值的某一列数据由 str类型转化为 int 类型
ele.loc[:,'cmte_id'] = ele['cmte_id'].str.replace('C','').astype('int64')
ele.head()
13.ndarray有广播机制,pandas没有广播机制,
广播机制: 1)缺维度的补维度
2)缺数据的补数据
14.pandas中多层索引变换: 默认 level = -1
stack(),level等于哪一个,哪一个就消失,出现在最里面的行里。
unstack(),level等于哪一个,哪一个就消失,出现在最里面的列里
10.画图的步骤 matplotlib ( 简洁步骤 )
-
创建画布
plt.figure(figsize=(20,8), dpi=100)
-
绘制图形
plt.plot()
-
显示图像
plt.show()
11.画图的步骤 matplotlib ( 详细步骤 )
-
首先创建 x轴,y轴数据
# 利用range();np.random模块等等创建 x,y的数据
-
创建画布
plt.figure(figsize=(10,10), dpi=100)
-
绘制折线图,散点图等图像
plt.plot(x,y)
-
自定义 x轴,y轴的刻度
# x轴:plt.xticks(非字符串的序列) # y轴:plt.yticks(非字符串的序列) ## 注意:如果要设置字符串的数据,那么必须放在 函数参数的第二位,来替换第一位参数的值 plt.xticks([非字符串], [字符串])
-
(可选)设置网格
# plt.grid(linestyle='-', alpha=0.5) # 参数: linestyle: 网格的样式 # alpha:透明度,范围是0到1之间
-
(可选)添加 x轴,y轴,整个图像的标题
# plt.xlabel('标题x', fontsize="文字的大小") # plt.ylabel('标题y', fontsize="文字的大小") # plt.title('图像标题', fontsize="文字的大小")
-
(可选)显示图例
# plt.legend(loc=值 ) # 与显示折线,散点等名字label配合使用 # 注意:一定要在plt.plot()里面设置一个label,如果不设置,没法显示
-
(可选)保存图片
# plt.savefig('保存路径') #** 保存图片必须在show()之前,否则保存不成功,因为show()方法执行后会立马释放figure资源
-
展示图像
# plt.show()
Python 阶段二
一, 进程和线程
1.为什么数据分析中不用python内置的数据类型,而使用 numpy 或者 pandas
- numpy和pandas的数据结构是要 优于 python内置的结构
- numpy中默认采用多进程的方式处理数据
- numpy底层是采用c来处理数据
2.并行:多个cpu同时处理多个程序
并发:一个cpu在一个很小的时间段之内在多个程序之间来回切换执行
3.__name__
的意义:
如果执行当前文件 __name__
== ‘__main__
’
如果是在其他文件中执行 __name__
== ‘文件的名称’
4.进程的创建方式
-
导包( dos系统导包放在if _ _ name _ _ = “_ main_” 后面 )
from multiprocessing import Process
-
创建多个函数
def1 ; def2 …
-
创建进程
# Process函数中必须包含一个 target参数,指定创建进程的函数名称 p1 = Process(target=run1)
-
执行进程
p1.start()
5.多线程的创建方式
-
导包
from threading import Thread
-
创建多个函数
def1 ; def2 … …
-
创建多个线程
t1 = Thread(target=run1)
-
执行线程
t1.start()
-
等待子线程执行完之后,在执行主线程
t1.join()
6.进程对象的 join 方法的意思: 阻塞进程 ( p1.join() )
7.守护进程和线程
- 作用: 当主进程或主线程结束之后,不管子进程或线程有没有结束,当前所有进程或线程全部结束
- 方法:子进程对象.daemon = True
- 子线程对象.setDaemon (True)
7.多进程之间数据不共享,如果需要多进程之间数据共享,最常用的三种方式
- 管理器 manager ==>参数元组或字典
- 队列 queue ==>先进先出 , 一端输入另一端输出 ( 同一个对象 )
- 管道 pipe ==>需要两个对象中其中一个输入,另一个对象接收
- 套接字 sock (不常用)
8.多线程之间数据是共享的, 但是共享会带来数据错乱,所以必须加锁解决
加锁的方法
- 加锁:lock.acquire()
- 释放锁:lock.release()
9.进程池和线程池
-
为什么要使用进程池和线程池:因为不会频繁的创建和销毁进程,所以节省资源
-
进程池中一般创建多少个进程,效率最高: 电脑中 cpu核数的 两倍
10.闭包一定要满足3个条件
- 外层函数一定要包含一个内层函数
- 外层函数一定返回内层函数的函数名称
- 内层函数一定是使用外层函数的变量
11.python中的多线程是伪多线程,因为GIL(全局解释性锁)的存在,所以多线程中cpu的执行是并发的,而不是并行的.
二.数据结构
1.计算机中的数据结构: 顺序表 , 链表 , 栈 , 队列 , 堆(二叉树)
三.数据算法
"""
继承:python2 中 多继承是深度优先继承 ,python3中 多继承为广度优先继承
"""
"""
二叉树遍历
# 1.广度优先遍历 ( 层次遍历 )
# 2.深度优先遍历 ( 先序 , 中序 , 后序) %% 确定二叉树的形状,先`中`后序至少需要二者,其中必须包含 中序 .
先序 : 中(根) ==> 左 ==> 右
中序 : 左 ==> 中 ==> 右
后序 : 左 ==> 右 ==> 中
大家在cmd中先输入:activate root, 然后再输入 jupyter notebook
四.Excel
1.函数offset和vlookup
offset偏移量不计算自身(即自身下一位为1开始计数) " 5 个参数 "
vlookup 显示偏移量从自身开始计算(即自身为1开始计数) " 4个参数 "
2.单元格地址引用(F4锁定单元格行,列索引)
"+"横着拉锁行索引,竖着拉锁列索引
3.match函数 与 index函数
match 函数有3个参数, 是根据数据找对应的位置(即索引), 函数第二个参数只能选择一列或者一行(即只能在一列或一行中确定目标数据的位置),不能选择多行或多列.
index 函数有3个参数, 是根据行号和列号来找出对应的数据,参数行和列和vlookup函数一样都是从自身开始计数, 参数选择区域任意.
4.datedif函数 计算日期差 计算目标值距离当前多久时间 ( “Y”,“M”,"D"分别表示年月日 )
datedif (目标单元格数据 , today() , “Y” ) ==> 计算目标值距离当前多少年?
datedif (目标单元格数据 , today() , “M” ) ==> 计算目标值距离当前多少月?
datedif (目标单元格数据 , today() , “D” ) ==> 计算目标值距离当前多少天?
五.正则表达式(re模块)
1.正则表达式的单字符匹配
. 表示匹配任意一个字符( 除了 \n )
[] 表示匹配’’[]"中列举的其中一个字符
\d 表示匹配数字0~9
\D 表示匹配非数字
\s 表示匹配空白 即 空格 和tab键
\S 表示匹配非空白
\w 表示匹配单词字符,即az,AZ,0~9,及下划线_
\W 表示匹配非单词字符
** 由于python中" \ "具有转义含义,一般使用正则表达式时第一个参数前最好加上’’ r’'防止转义,表示原生字符
2.正则表达式中表示数量
" * " 表示匹配前一个字符出现0次或者无限次,即可有可无
" + " 表示匹配前一个字符出现1次或者无限次,即至少有一次
" ? " 表示匹配前一个字符出现1次或者0次,即要么1次 要么没有
" {m} " 表示匹配前一个字符出现m次. 如{8} 表示前一个字符出现8次
“{m},” 表示匹配前一个字符至少出现m次
“{m,n}” 表示匹配前面一个字符出现从m到n次
3. 正则表达式表示边界
" ^ " 表示匹配字符串开头
" $ " 表示匹配字符串结尾
" \b " 表示匹配一个单词的边界
" \B " 表示匹配非单词边界
六.线性代数
1.矩阵之间的加减法必须是同型矩阵对应元素相加减
矩阵与数的乘法,称为数乘,即矩阵中每个元素和数k相乘.
矩阵与矩阵相乘必须是A 矩阵的列数 等于 B矩阵的行数
2.矩阵乘法不满足交换律,不满足消去律, 两个非零矩阵相乘可以得到零矩阵
3.矩阵的转置 注意 ABT=BT∗ATAB^{T} = B^{T}*A^{T}ABT=BT∗AT 可以推广为(ABC)T=CTBTAT(ABC)^{T} = C^{T}B^{T}A^{T}(ABC)T=CTBTAT
1.对换矩阵中的第i,ji,ji,j两行(列)的位置, 记做rij(cij)或r_{ij}(c_{ij})或rij(cij)或ri<−>rj(ci<−>cj)r_i <->r_j (c_i <-> c_j)ri<−>rj(ci<−>cj)
2.用非零常数k乘第iii行(列), 记做kri(kci)kr_i(kc_i)kri(kci)
3.用矩阵的第jjj行(列)乘以常数kkk后加到第iii行(列)对应元素上去, 记做ri+krj(ci+kcj)r_i + kr_j(c_i + kc_j)ri+krj(ci+kcj)
定理: 任何一个矩阵都有等价标准型
- 矩阵的秩
1.奇异矩阵 |A| = 0,反之非奇异矩阵
满秩的矩阵为非奇异矩阵,降秩的矩阵为非奇异矩阵
- 逆矩阵的求法
方法一: 用A⋆求A−1=1∣A∣A⋆A^{\star}求A^{-1} = \frac{1}{|A|}A^{\star}A⋆求A−1=∣A∣1A⋆
方法二: 初等变换法.
A可逆⇒A−1可逆,那么A−1就是非奇异的,也就是说A逆最终可以转化为单位矩阵,那么反过来单位矩阵经过相反的初等变换就可以得到A−1A可逆\Rightarrow A^{-1}可逆, 那么A^{-1}就是非奇异的, 也就是说A逆最终可以转化为单位矩阵,那么反过来单位矩阵经过相反的初等变换就可以得到A^{-1}A可逆⇒A−1可逆,那么A−1就是非奇异的,也就是说A逆最终可以转化为单位矩阵,那么反过来单位矩阵经过相反的初等变换就可以得到A−1
(A⋮E)→行变换→(E⋮A−1)(A\vdots E) \rightarrow 行变换 \rightarrow (E\vdots A^{-1})(A⋮E)→行变换→(E⋮A−1)
只需要将A变成单位矩阵, 同时对E操作, 得到的矩阵就是A的逆矩阵.
七.机器学习
1.算法 ( 分类 和回归 )
-
knn(分类): 预测准确率很高,计算稍复杂
-
线性回归 (回归) :
-
梯度下降
-
岭回归 (回归) : 在线性回归的基础上稍加改进(样本数据不够时可以使用)
-
lasso回归 (回归) : 需要调节创建对象参数alpha尽可能小
-
逻辑斯蒂回归(分类) : 是用来处理分类问题 ( 经典二分类)
-
决策树 :一棵树 *需要注意的是使用决策树时,要调整适合的树深度,不然容易出现过拟合现象
-
随机森林(属于集成算法) : 许多树组成的森林
-
随机森林
随机的含义:-
随机取样本, 每棵树的样本是相同.
-
随机取特征, 每棵树的特征数是相同.
分类: 投票, 少数服从多数
回归: 求平均.
-
-
ID3算法-> 计算信息增益.
优点: 简单好理解
缺点: 1. 会优先以离散特征进行划分,可能会造成误差.2. 存在大量的对数运算.
*** C4.5算法 是ID3的改进算法, 它计算信息增益率(就是选择信息增益率最高的那个特征进行分类). 它针对ID3缺点中的第一个缺点进行改进. -
CART算法使用基尼系数来决定优先以哪个特征进行划分.
基尼系数表达的物理含义和信息熵是一样的, 都表示系统不确定性的度量.系统中的事情越确定, 基尼系数越低, 越不确定, 基尼系数越高.
gini系数是在0到1之间.
*** ID3和C4.5是只能做分类问题. CART还可以做回归.
CART 生成的是二叉决策树. -
-
画图形边界 ( 代码模板)
# 把x,y轴等分
x, y = np.linspace(data[:, 0].min(), data[:, 0].max(), 1000), np.linspace(data[:, 1].min(), data[:, 1].max(), 1000)
# x 轴 y轴分别画直线相交
X, Y = np.meshgrid(x, y)
# 把线相交的点取出来.
XY = np.c_[X.ravel(), Y.ravel()]
# 画边界区域和散点图
# y_= 算法预测(如y_ = knn.predict(XY))
plt.scatter(XY[:, 0], XY[:, 1], c=y_)
#或: plt.pcolormesh(X, Y, y_.reshape(1000, 1000))
plt.scatter(data[:, 0], data[:, 1], c=target, cmap='rainbow')
优点: 简单好理解
缺点: 1. 会优先以离散特征进行划分,可能会造成误差.2. 存在大量的对数运算.
*** C4.5算法 是ID3的改进算法, 它计算信息增益率(就是选择信息增益率最高的那个特征进行分类). 它针对ID3缺点中的第一个缺点进行改进.
-
CART算法使用基尼系数来决定优先以哪个特征进行划分.
基尼系数表达的物理含义和信息熵是一样的, 都表示系统不确定性的度量.系统中的事情越确定, 基尼系数越低, 越不确定, 基尼系数越高.
gini系数是在0到1之间.
*** ID3和C4.5是只能做分类问题. CART还可以做回归.
CART 生成的是二叉决策树.
- 画图形边界 ( 代码模板)
# 把x,y轴等分
x, y = np.linspace(data[:, 0].min(), data[:, 0].max(), 1000), np.linspace(data[:, 1].min(), data[:, 1].max(), 1000)
# x 轴 y轴分别画直线相交
X, Y = np.meshgrid(x, y)
# 把线相交的点取出来.
XY = np.c_[X.ravel(), Y.ravel()]
# 画边界区域和散点图
# y_= 算法预测(如y_ = knn.predict(XY))
plt.scatter(XY[:, 0], XY[:, 1], c=y_)
#或: plt.pcolormesh(X, Y, y_.reshape(1000, 1000))
plt.scatter(data[:, 0], data[:, 1], c=target, cmap='rainbow')