复习提纲
一、python语言的特点
-
简单:Python 是一种代表简单主义思想的语言。阅读一个良好的 Python程序就感觉像是在读英语一样,尽管这个英语的要求非常严格。Python的这种伪代码本质是其优点之一,使用户能够专注于解决问题而不是去搞明白语言本身。
-
易学:Python 有极其简单的语法,非常容易上手。
-
免费、开源:Python 是 FLOSS(*/开源软件)之一。简单来说,用户可以*地发布这个软件的拷贝、阅读它的源代码、对它做改动、把它的一部分用于新的*软件中。FLOSS 是基于一个团体分享知识的概念,这也是为什么 Python 如此优秀的原因之一:它由一群希望看到 Python更加优秀的人创造,并被他们不断改进。
-
高层语言:使用 Python 语言编写程序时,不用考虑如何管理程序使用的内存等底层细节。
-
可移植性强:由于它的开源本质,Python 已经被移植在许多平台上。如果 Python 程序没有使用依赖于系统的特性,那么程序不用修改就可以在下述任意平台上面运行。这些平台包括
Linux、Windows、FreeBSD、Macintosh、Solaris、OS/2、Amiga、AROS、AS/400、BeOS、OS/390、z/OS、Palm
OS、QNX、VMS、Psion、Acom RISC OS、VxWorks、PlayStation、Sharp
Zaurus、Windows CE、Pocket PC 和 Symbian。 -
解释型语言:编译型语言(如 C 或 C++)源程序从源文件(即 C 或 C++ 语言)转换到二进制代码(即 0 和 1)的过程通过编译器和不同的标记、选项完成,当运行程序的时候,连接器把程序从硬盘复制到内存中并且运行。而 Python
程序不需要编译成二进制代码,直接从源代码运行程序。 -
面向对象:Python 既支持面向过程的编程也支持面向对象的编程。在面向过程的语言中,程序是由过程或仅仅是可重用代码的函数构建起来的。在面向对象的语言中,程序是由数据和功能组合而成的对象构建起来的。与其他语言(如
C++ 和 Java)相比,Python 以一种非常强大又简单的方式实现面向对象编程。 -
可扩展性强:如果希望把一段关键代码运行得更快或希望某些算法不公开,可以使用 C 或 C++ 语言编写这部分程序,然后在 Python 程序中调用它们。
-
可嵌入性强:可以把 Python 嵌入 C/C++ 程序,从而向用户提供脚本功能。
-
丰富的扩展库:Python 扩展库很庞大,可以帮助处理包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV
文件、密码系统、GUI(图形用户界面)、Tk 以及其他与系统有关的操作。只要安装了 Python,所有这些功能都是可用的,这被称作
Python 的“功能齐全”理念。除了扩展库以外,还有许多其他高质量的库,如 wxPython、Twisted 和 Python
图像库等。
缺点:速度慢、对多处理器的利用不充分
二、python语言的执行过程
- Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后虚拟机一条一条执行字节码指令,从而完成程序的执行
三、面向对象编程,会编写类函数
定义:
Python使用class关键字来定义类,class关键字之后是一个空,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现。
类名的首字母一般要大写,当然也可以按照自己的习惯定义类名,但一般推荐参考惯例来命名,并在整个系统的设计和实现中保持风格一致,这一点对于团队合作尤其重要。
class Car:
def infor(self):
print("This is a car")
定义了类之后,可以用实例化对象,并通过"对象名.成员"的方式来访问其中的数据成员或成员方法。
class Car:
def infor(self):
print("This is a car ")
car = Car()
car.infor()
This is a car
编写类函数
class Car:
price = 10 #定义类属性(价格),Car的价格都是10万
def __init__(self,c):
self.color = c #定义实例属性
car1 = Car("Red") #实例化对象(car1为红色)
car2 = Car("Blue")
print(car1.color,Car.price) #查看实例(car1)的属性(价格,颜色)
Car.price = 11 #修改类(Car)的属性(价格)
Car.name = "QQ" #动态增加类属性,(所有的Car都叫QQ)
car1.color = "Yellow" #修改实例属性(car1的颜色被修改)
print(car2.color,Car.price,Car.name)
print(car1.color,Car.price,Car.name)
Python类型的动态性使得我们可以动态为自定义类及其对象增加新的属性和行为,俗称混入(mixn)机制,这在大型项目开发中会非常方便和实用。
简单应用
先定义类(一个car的.py文件)
class car:
def __init__(self,brand,color,price): #注意是init不是int
self.brand = brand
self.color = color
self.price = price
####################################男人的选择标准#################################
def on_man_list(self):
if self.price >= 35:
return True
else:
return False
####################################女人的选择标准#################################
def on_women_list(self):
if self.color == "pink":
return "满意,是我喜欢的颜色"
else:
return "不满意,换个颜色"
接着新建一个新的.py
from car import car
##############################搞出car1~4让男女进行选择#########################
car1 = car("QQ", 'pink', 20)
car2 = car("Audi", 'black', 30)
car3 = car("volvo","pink",35)
car4 = car("Lincoln","white",40)
###################################显示出判断的结果############################
print(car1.on_man_list())
print(car1.on_women_list())
print(car2.on_man_list())
print(car2.on_women_list())
print(car3.on_man_list())
print(car3.on_women_list())
print(car4.on_man_list())
print(car4.on_women_list())
执行结果
False
满意,是我喜欢的颜色
False
不满意,换个颜色
True
满意,是我喜欢的颜色
True
不满意,换个颜色
公有和私有成员
- Python并没有对私有成员提供严格的访问保护机制。
- 在定义类的成员时,如果成员名以两个下划线“__”开头则表示是私有成员。私有成员在类的外部不能直接访问,需要通过调用对象的公有成员方法来访问,也可以通过Python支持的特殊方式来访问。
- 公有成员既可以在类的内部进行访问,也可以在外部程序中使用。
在Python中,以下划线开头的变量名和方法名有特殊的含义,尤其是在类的定义中。用下划线作为变量名和方法名前缀和后缀来表示类的特殊成员:
- _xxx:受保护成员,不能用’from module import *'导入;
- xxx:系统定义的特殊成员;
- __xxx:私有成员,只有类对象自己能访问,子类对象不能直接访问到这个成员,但在对象外部可以通过“对象名._类名__xxx”这样的特殊方式来访问。
注意:Python中不存在严格意义上的私有成员。
方法
在类中定义的方法可以粗略分为四大类:公有方法、私有方法、静态方法和类方法。
- 公有方法、私有方法都属于对象,私有方法的名字以两个下划线“__”开始,每个对象都有自己的公有方法和私有方法,在这两类方法中可以访问属于类和对象的成员;
- 公有方法通过对象名直接调用,私有方法不能通过对象名直接调用,只能在属于对象的方法中通过self调用或在外部通过Python支持的特殊方式来调用。
- 如果通过类名来调用属于对象的公有方法,需要显式为该方法的self参数传递一个对象名,用来明确指定访问哪个对象的数据成员。
- 静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。
- 静态方法可以没有参数。
- 一般将cls作为类方法的第一个参数名称,但也可以使用其他的名字作为参数,并且在调用类方法时不需要为该参数传递值。
四、numpy数组定义和运算、切片
定义:
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6]]) #直接赋值定义
>> [[1 2 3]
[4 5 6]]
A = np.array([1, 2, 3],dtype=complex) #定义了一个负数complex。
>>[1.+0.j 2.+0.j 3.+0.j]
np.arange(0, 1, 0.2) #(起始值,终点值,间隔)
>> [ 0. , 0.2, 0.4, 0.6, 0.8]
np.linspace(0, 5, 6) #(起始值,终点值,取点数)
>> [0. 1. 2. 3. 4. 5.]
np.zeros((2,3)) #全0(行,列)向量
>>[[ 0., 0., 0.],
[ 0., 0., 0.]]
np.eye(3) #对角线上全为1
>>[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
加减运算:
a = np.arange(4)
>> ([0, 1, 2, 3])
b = np.array([2, 3, 2, 4])
a * b
>> ([ 0, 3, 4, 12])
b - a
>> ([2, 2, 0, 1])
c = [2, 3, 4, 5]
a * c
>>([ 0, 3, 8, 15])
向量的普通内积
u = [1, 2, 3]
v = [1, 1, 1]
np.inner(u, v)
>>6 #1*1+2*1+3+1=6
向量的外积
u = [1, 2, 3]
v = [4, 5, 6]
np.outer(u, v)
>>[[ 4 5 6] #[1*4 1*5 1*6]
[ 8 10 12] #[2*4 2*5 2*6]
[12 15 18]] #[3*4 3*5 3*6]
向量的乘法
A = np.ones((3, 2)) #3行2列全1向量
>>[[ 1., 1.],
[ 1., 1.],
[ 1., 1.]]
A.T #转置3行2列变成2行3列
>>[[ 1., 1., 1.],
[ 1., 1., 1.]]
B = np.ones((2, 3)) #2行3列全1向量
>>[[ 1., 1., 1.],
[ 1., 1., 1.]]
#--------------M行N列的向量和N行O列的向量点乘结果为M行O列的向量--------------#
np.dot(A, B)
>>[[ 2., 2., 2.],
[ 2., 2., 2.],
[ 2., 2., 2.]]
np.dot(B, A)
>>[[ 3., 3.],
[ 3., 3.]]
np.dot(B.T, A.T)
>>[[ 2., 2., 2.],
[ 2., 2., 2.],
[ 2., 2., 2.]])
点积vdot
返回两个向量的点积。
vdot(a,b)函数对复数的处理方式与点(a,b)不同。如果第一个参数是复数,则将第一个参数的复共轭用于点积的计算。注意,vdot处理多维数组不同于dot:它不执行矩阵乘积。因此,它仅应用于向量。
a=np.array([[3,4],[5,6]])
b=np.array([[10,11],[12,13]])
c=np.vdot(a,b)
>>212 #3*10+4*11+5*12+6*13
运算方法相同
a=np.array([1+2j,3+4j])
b=np.array([5+6j,7+8j])
c=np.vdot(a,b)
>>(70-8j)
d=np.vdot(b,a)
>>(70+8j)
关于切片
直接上链接彻底搞懂Python切片操作
a = np.array([[1, 2],[3, 4],[5, 6]])
a
>>[[1 2]
[3 4]
[5 6]]
a[0]
>>[1 2]
a[0][1]
>>2
b = np.arange(6)
b
>>[0 1 2 3 4 5]
b[1:3]
>>[1 2]
b[:3]
>>[0 1 2]
b[3:]
>>[3 4 5]
b[0:4:2]
>>[0 2]
五、矩阵的特征值、特征向量手工和numpy编程实现
- 在numpy中就这——np.linalg.eig()
import numpy as np
w, v = np.linalg.eig(np.array([[1, -2], [2, -3]]))
print('特征值:{}\n特征向量:{}'.format(w,v))
运行结果
特征值:[-0.99999998 -1.00000002]
特征向量:[[0.70710678 0.70710678]
[0.70710678 0.70710678]]
手工计算
这部分麻烦大家静下心来慢慢看,不要因为是英文就烦躁。数学都是符号,和英语水平无关的。
pandas的两种主要数据类型Series和DataFrame包含的主要属性和方法,构造Series和DataFrame实例的方法pandas数据切片
麻烦大家把pandas和excel做类比
Series结构很简单,就是索引列和数据列(n行2列),Dataframe就很像excel了。
接下来就开始代码理解。
参考链接
创建Series和DataFrame
先导入
import numpy as np
import pandas as pd
创建对象,构造实例
Series
s = pd.Series([1, 3, 5, np.nan, 6, 8])
s
>>
0 1.0
1 3.0
2 5.0
3 NaN #缺省值
4 6.0
5 8.0
dtype: float64
DataFrame
dates = pd.date_range("20130101", periods=6)
dates
>>
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
'2013-01-05', '2013-01-06'],
dtype='datetime64[ns]', freq='D')
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list("ABCD"))
df
>>
A B C D
2013-01-01 0.469112 -0.282863 -1.509059 -1.135632
2013-01-02 1.212112 -0.173215 0.119209 -1.044236
2013-01-03 -0.861849 -2.104569 -0.494929 1.071804
2013-01-04 0.721555 -0.706771 -1.039575 0.271860
2013-01-05 -0.424972 0.567020 0.276232 -1.087401
2013-01-06 -0.673690 0.113648 -1.478427 0.524988
或者通过传递对象的字典来创建,这些对象可以转换为类似序列的对象。
df2 = pd.DataFrame(
{
"A": 1.0,
"B": pd.Timestamp("20130102"),
"C": pd.Series(1, index=list(range(4)), dtype="float32"),
"D": np.array([3] * 4, dtype="int32"),
"E": pd.Categorical(["test", "train", "test", "train"]),
"F": "foo",
}
)
df2
>>
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo
说白了就是利用自带的函数进行的创建,相当与Excel里自动填充单元格的操作。
方法
基本上就是在读英文,要实现自行输入或者看参考链接。
对于缺省值的处理方法
- 均值:df.mean
- 标准差 df.std
- 方差 df.var
- 中位数df.median
- 众位数df.mode
查看数据的方法
- 显示统计数据:df.describe()
- 查看框架顶部行的方法:df.head() /默认是5行
- 查看框架底部行的方法:df.tail()
- 显示索引:df.index
- 显示列:df.columns
- 将DataFrame转换为NumPy数组:DataFrame.to_numpy
切片
选择一个单列,产生一个Series,等于df.A:
df["A"]
>>
2013-01-01 0.469112
2013-01-02 1.212112
2013-01-03 -0.861849
2013-01-04 0.721555
2013-01-05 -0.424972
2013-01-06 -0.673690
Freq: D, Name: A, dtype: float64
选择via [ ],对行进行切片。
df[0:3]
>>
A B C D
2013-01-01 0.469112 -0.282863 -1.509059 -1.135632
2013-01-02 1.212112 -0.173215 0.119209 -1.044236
2013-01-03 -0.861849 -2.104569 -0.494929 1.071804
df["20130102":"20130104"]
>>
A B C D
2013-01-02 1.212112 -0.173215 0.119209 -1.044236
2013-01-03 -0.861849 -2.104569 -0.494929 1.071804
2013-01-04 0.721555 -0.706771 -1.039575 0.271860
或者通过label
df.loc[dates[0]]
>>
A 0.469112
B -0.282863
C -1.509059
D -1.135632
Name: 2013-01-01 00:00:00, dtype: float64
df.loc["20130102":"20130104", ["A", "B"]]
>>
A B
2013-01-02 1.212112 -0.173215
2013-01-03 -0.861849 -2.104569
2013-01-04 0.721555 -0.706771
还有.icol
df.iloc[1:3, :]
>>
A B C D
2013-01-02 1.212112 -0.173215 0.119209 -1.044236
2013-01-03 -0.861849 -2.104569 -0.494929 1.071804
emmm…好多种方法,再次附上参考链接
七、python中包、模块以及函数的概念
模块
- 一个.py文件就是一个模块。这个文件的名字是:模块名.py。由此可见在python中,文件名和模块名的差别只是有没有后缀。有后缀是文件名,没有后缀是模块名。
- 每个文件(每个模块)都是一个独立的名称空间,也就是说可以在两个(多个)文件中出现同名的函数。
创建
在python中,有三种方式去创建模块:
- 自己写一个python文件;
- 用C语言实现,然后在运行时动态加载,比如常用的正则表达式模块re ;
- 内置模块,我们直接引用就可以了;(numpy、pandas等等)
先自己创建一个model.py
s = "If Comrade Napoleon says it, it must be right."
a = [100, 200, 300]
def foo(arg):
print(f'arg = {arg}')
class Foo:
pass
另一个同文件夹下的XXX.py
import model as mod
print(mod.s)
>>If Comrade Napoleon says it, it must be right.
mod.a
>>[100, 200, 300]
mod.foo(['quux', 'corge', 'grault'])
>>arg = ['quux', 'corge', 'grault']
None
包
- 包的本质就是一个包含__init__.py文件的目录。是一种通过使用‘.模块名’来组织python模块名称空间的方式,也就是说在在导入包时遇到带
点 的,这就是关于包的导入语法。 - 导入包,本质上是导入了包中的__init__.py文件。
- 包的导入形式也有,import 和 from…import…两种形式
参考链接
八、import的含义,知道从模块导入函数或类、从包导入模块的实现过程
import modname
模块是指一个可以交互使用,或者从另一Python 程序访问的代码段。只要导入了一个模块,就可以引用它的任何公共的函数、类或属性。模块可以通过这种方法来使用其它模块的功能。
用import语句导入模块,就在当前的名称空间(namespace)建立了一个到该模块的引用.这种引用必须使用全称,也就是说,当使用在被导入模块中定义的函数时,必须包含模块的名字。所以不能只使用 funcname,而应该使用 modname.funcname
九、字符串、序列、集合、字典、元组的加减乘除基本运算
十、掌握input输入
- Python3.x 中 input() 函数接受一个标准输入数据,返回为 string 类型。
- 注意:在 Python3.x 中 raw_input() 和 input() 进行了整合,去除了 raw_input( ),仅保留了input( )函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。
函数语法
input([prompt]) #prompt: 提示信息
实例
这个实例在python(命令指令符->python)里运行可能或更好的理解
a = input("input:")
>>input:123 #输入整数
a
>>'123'
type(a)
>> <class 'str'> # 字符串
题目:语句X=input()执行时,输入123后按回车键,则X的值是 “123”
十一、TF_IDF的手工计算,sklearn编码实现,某单词的IDF计算公式=log10
TF表示术语频率,而TF_IDE表示术语频率乘以逆文档频率:TF_IDE=TF*IDF
在TfidfTransformer和TfidfVectorizer 中smooth_idf=False,将“ 1”计数添加到idf中,而不是idf的分母中:
程序实现:
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
sentences = [
'There is a boy',
'There is a girl',
'They are humans'
]
Vectorizer = CountVectorizer()
X = Vectorizer.fit_transform(sentences)
print(X.toarray())
features = Vectorizer.get_feature_names()
print(features)
tfidf = TfidfVectorizer()
result = tfidf.fit_transform(sentences)
print(result)
TIP:默认配置通过提取至少2个字母的单词来标记字符串,比如"a"会被自动忽略不纳入计算。
[[0 1 0 0 1 1 0]
[0 0 1 0 1 1 0]
[1 0 0 1 0 0 1]]
['are', 'boy', 'girl', 'humans', 'is', 'there', 'they']
(0, 1) 0.680918560398684
(0, 4) 0.5178561161676974
(0, 5) 0.5178561161676974
(1, 2) 0.680918560398684
(1, 4) 0.5178561161676974
(1, 5) 0.5178561161676974
(2, 3) 0.5773502691896257
(2, 0) 0.5773502691896257
(2, 6) 0.5773502691896257
十二、能够用sklearn线性回归算法,对给定的数据集进行线性回归学习
十三、独热编码
独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。
自然状态码为:000,001,010,011,100,101
独热编码为:000001,000010,000100,001000,010000,100000
好处:
- 解决了分类器不好处理属性数据的问题
- 在一定程度上也起到了扩充特征的作用
sklearn实现:
>>> from sklearn import preprocessing
>>> enc = preprocessing.OneHotEncoder()
>>> X =[['male', 'US', 'Safari'], ['female','Europe','Firefox']]
>>> enc.fit(X)
OneHotEncoder()
>>> enc.transform([['female', 'US', 'Safari'], ['male','Europe','Firefox']]).toarray()
array([[1., 0., 0., 1., 0., 1.], #"0.,1."表示male、US、Safari
[0., 1., 1., 0., 1., 0.]]) #"1.,0."表示female、Europe、Firefox
结束语
Python的优点之一就是使用户能够专注于解决问题而不是去搞明白语言本身,其实阅读一个良好的 Python程序就感觉像是在读英语一样。
- 基本上考点在老师给的PPT上都有,大家静下心来都能找到,本文仅供参考。
- 愿大家在新的一年里乘风破浪,更近一步。预祝大家(包括我自己