0%

Python Study Notes I

【环境】
win10,python3.8.0,anaconda3

【安装、运行与退出、交互】

安装:官网下载,安装时需要add to environment viablity,否则无法在命令运行符里交互。

运行:win10下运行cmd或直接搜索进入命令运行符,输入python,如返回显示python版本号,且提行显示>>>待输入命令,则已运行python,可直接在>>>后输入命令,如:输入1+1,回车返回2;输入print('hello world'),回车返回hello world

退出:在>>>后输入exit(),则退出python

交互
1)可以在命令运行符下,输入python进入python环境,再输入python语句回车看结果;
2)也可以在命令运行符下,先cd 文件目录,再输入python filename.py,看结果。
注意:如果.py文件里没有把计算结果print()出来,那么尽管计算了但不会返回结果;如果在命令运行符里不是输入的python filename.py而是直接输入filename.py,那么不会运行.py里的代码,而是会打开这个.py文件

How to code
新建一个.py文件,用文本编辑器如sublime打开,在里面写全部代码;
同时开着命令运行符,运行python,随时把其中的代码丢到>>>后面去运行看效果

【输入输出】

输出print('','','') 注:在显示时,三个信息会依次显示,逗号会显示为一个空格

输入input('words shown when ask for input')

举例:

1
2
name=input('Please enter your name: ')
print('Hello',name)

新建一个.py文件,并在里面写下如上所示代码,并在命令运行符中python test.py
则会返回提示Please enter your name:,在其后输入Anna,
则会返回结果Hello Anna

【字符编码】

python本身是使用unicode的,兼容多种编码。但保存的.py文件python一般会用ascii编码去读,如果源代码全是英文没问题,但如果有中文会报错或读取为乱码,需要在.py文件最前面加上如下两行注释,来让它用utf-8编码去读:

1
2
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

第一行注释是让Linux或OS X系统知道这是一个python可执行程序,Windows系统会忽略这行。
第二行注释是让python知道要用utf-8编码去读这个源代码。

除了让python知道要用utf-8去读文件以外,还需要把.py文件本身用utf-8编码,这样才能被python读取到中文。最简单的方法是用把.py文件用记事本打开,另存为编码为“不带BOM的UTF-8”的副本即可。sublime里实现这个需要自定义package,因比记事本法复杂暂不赘述。

【格式】

缩进:约定俗成四个空格作为缩进

大小写:python是大小写敏感的,注意选对大小写

浮点数:较大或较小的数字按照科学计数法表示,如125000=1.25e5,即1.25乘以10的5次方,同理,0.0000125=1.25e-5

字符串:原则上用''框起来,如果字符串中本身包含'则用""框起来,如"I'm okay",如果字符串本身既包含''又包含""则用\标志在字符串内的引号前,如'I\'m \"ok\!"=I’m “ok”!

布尔值:真True,假False,与and,或or,非not

空值None

变量赋值:python中的变量赋值用=,如x=1 x=x+2。新赋值会覆盖旧赋值,且可以和旧赋值的类型不同,如x=1 x='abc',在java中则不行,后者必须始终是数值或者始终是字符串。
变量命名习惯上一般有两种方法,一种是用下划线,如to_do_list,一种是第二个词开始首字母大写,如toDoList

常量表示:圆周率PI,自然常数e

【常见计算】
==:等于
!=:不等于
a**b : a的b次方
a/b:a除以b的精确值
a//b:a除以b所得值的整数部分
a%b:a除以b的余数
round(x, n):用四舍五入法取x的n位小数
range(m):生成从0到m-1共m个值的整数序列[0,1,2,...,m-1]

【特殊字符】

转义字符
转义字符\\n换行,\t制表符。需要直接表示\用\\。如\太多用\\有歧义需用r’’表示不转义,如

1
r`\\\t\\`

表示\\\t\\,而不是\ \

占位符
格式为%?,?表示替换内容的格式,%s表示用字符串替换,如果不知道该用什么就可以都用它,这样会把别的格式比如数字转化为字符串来替换,%d用整数替换,%f用浮点数替换,%x用十六进制整数替换。其中整数和浮点数可以在前面规定精确到的小数位数或是否在前面补0,如%2d,%02d,%.2f。使用方法举例:

1
2
# 想输出“尊敬的张三,会员号N-21-00233,您的余额为100.50元。”,可写为:
print('尊敬的%s,会员号N-%1d-%05d,您的余额为%.2f元' % ('张三', 21, 233, 100.5))

同样,需要直接表示%用`%%`,使用举例:
小明上学期72分,这学期85分,需要告诉小明他成绩提升了多少百分比,精确到小数点后一位,可写为:

undefined

【数列】
不可变数列tuple(又称元组):一旦定义后就不能修改
t=(1, [2, 3]),可以在tuple里嵌套list,里面的1和[]的位置不能修改,但[]里的可以修改。
t=(1,)为避免小括号的歧义,如果表tuple而里面的数组只有一个取值时需要加逗号。
t=(1, 'anna', 2.33),一个组里可以同时有不同格式整数、字符串、浮点数等。

可变数列list(又称数组):定义后可以修改
len(L)求list里包含的数值个数
listname[0], listname[1], listname[2], listname[-1]求数组中第1、第2、第3、倒数第1个值,如果超出长度没有取值会报错
listname[1][0]取数组中第2个值也是一个子数列中的第1个值
listname[n:m],又称作“切片”。取数组中第n个到第m个值[nvalue, n+1value,...,m-1value, mvalue],可省略n或m,表示从开头取到m或从n取到结尾,n和m均可用负数表示倒数第n或m个值。
listname.append('ToBeAdd')追加到列最后
listname.insert(2,'Tobeadd')插入到数列第3个值的位置
listname.pop()删除最后一个值
listname.pop(1)删除数列第2个值
listname[2]='abc'替换数列第3个值

【集合】
一种是只有key的集合set:
setname=set([1,2,3,3,4,5,5,6]),注意set的key是不重复的,按前面的输入后会自动去掉重复值。
setname.add(keytobeadd)向已建set里添加key
setname.remove(keytoberemove)删除key

一种是有value和key对应的集合dict(又称字典):
dictname={'key1':value1, 'key2':value2, 'key3':value3},新建dict。dict在建立的时候key就定下来了,不能修改,只有每个key对应的value可以改。
dictname[keyn]=valuen,在已建dict里为第n个key赋值valuen。可先通过'keyn' in dictname看返回是True还是False来检查keyn是否存在,如果已经存在,会覆盖原来的值,如果不存在,会新增keyn这个key。
dictname.pop(keynamem),删除keynamem及其对应的valuem,注意是()不是[]
把dict拆成数列输出:
dict.keys(),输出所有key的数列,
dict.values(),输出所有value的数列,
dict.items(),输出把key-value变成tuple的数列list,如list(dict.items())会输出[(key1,value1),(key2,value2)...]
dict和list一样,都可以嵌套多层形成多维数组。在定义dict的时候用`{{}}`,但查询的时候用[][]就好。

【条件判断】
python的条件判断使用if else,可嵌套多层,基本格式如下:

1
2
3
4
5
6
7
8
if 条件1:
执行1
elif 条件2:
执行2
elif 条件3:
执行3
else:
执行4

注意:
1)冒号:与缩进
2)如果需要判断的条件是input的,那么默认input的是字符串,如果要进行数字相关判断,需要用int(inputletters)float(inputletters)来把字符串转换成整数或浮点数后再进行判断,否则会报错。
3)if可以嵌套多层,每层if都需要比之前那层缩进4空格,否则会报错。

【循环】
python的循环语句有两种,一种是for x in []:,一种是while x< :,具体基本格式如下:
假设需要求1加到100,可以有两种写法:

1
2
3
4
sum = 0
for x in range(101):
sum = sum + x
print(sumnum)

注意x和sum的定义,及for in后的冒号和缩进。

1
2
3
4
5
6
x=1
sum=0
while x <= 100:
x = x + 1
sum = sum + x
print(sum)

在使用while中,可以使用break提前退出循环,或使用continue跳过当前循环开始下一次循环。
但能不用最好不要用,break和continue使用多了以后如果出错容易死循环,最好尽量还是使用for in和while控制条件来实现。
break使用范例:

1
2
3
4
5
n=1
while n<=100:
print(n)
n=n+1
print('END')

以上表示打印1到100,最后打印END,如果希望打到10的时候就停止,可以修改为:

1
2
3
4
5
6
7
n=1
while n<=100:
if n>10:
break
print(n)
n=n+1
print('END')

continue使用范例:

1
2
3
4
n=1
while n<=10:
n=n+1
print(n)

以上表示打印1到10,如果希望只打印奇数,可以修改为:

1
2
3
4
5
6
n=1
while n<=10:
n=n+1
if n%2=0:
continue
print(n)

【内置函数】
参见python官方文档

【自定义函数】
基本格式(注意冒号和缩进,冒号后缩进范围内会视为函数,未缩进不视为):

1
2
3
def functionname(x):
...
return ...

函数的参数可以有多个,如

1
2
def func(x,y):
return x+y

函数的参数还可以是开关,如

1
2
3
4
5
6
7
def func(x,y,method)
if method=='plus':
return x+y
elif method=='minus':
return x-y
else:
print('error')

参数可以设置默认参数,如

1
2
3
4
5
6
7
def func(x,y=1,method='plus')
if method=='plus':
return x+y
elif method=='minus':
return x-y
else:
print('error')

进行上面的修改后,表示如果输入func(x)则默认输出x+1,输入func(x,y),则默认输出x+y,输入func(x,y,'plus'/'minus')才按照完整的函数进行计算。
自定义函数可以进行复杂的多步运算,return的可以是多个值,如果值超过1个是,python会以tuple形式返回。

调用自定义函数:
把自定义的functionname()函数保存为functionfile.py文件,然后在运行cmd中进入python后调用:

1
2
3
4
>>> from functionfile import functionname
>>>functioname(input)
output
>>> _

如果没有想好定义的函数具体要怎么做,可以用pass定义一个空函数,这样让程序先跳过这里运转起来,避免报错。

1
2
def nop()
pass

pass作为占位符,不仅可以用在定义空函数里,也可以用在其他语句里。

【包/类/模块】
他人写好的保存为.py的自定义函数,称为模块,一些模块组成一个类,一些类组成一个包。
一些常见包:
数据分析:pandas,numpy,scipy
绘图:matplotlib, seaborn
机器学习:scikit-learn, Gensim, NLTK
爬虫:urllib, BeautifulSoup

安装包:运行cmd,输入pip install pandas,如果没安装会进行安装。
也可采用一些集成了若干包的工具软件,比如Anaconda,集成了主流数据分析pandas numpy scipy、绘图matplotlib、机器学习scikit-learn的包,可以直接去官网下载安装软件。

加载包:import pandas,每次使用前都需加载。

【numpy】
每次使用前载入,用as取别名方便调用:
import numpy as np

创建一维数组:

1
2
3
4
>>>data1=[1,2,3,4,5]
...array1=np.array(data1)
>>>array1
>>>array([1,2,3,4,5])

创建多维数组:

1
2
3
4
5
>>>data2=[[1,2,3],[4,5,6]]
...array2=np.array(data2)
>>>array2
>>>array([[1,2,3],
[4,5,6]])

一个array内部的元素必须是相同类型,都是数值或都是都是字符组,查询数组类型:

1
2
>>>array2.dtype
>>>dtype('int32')

数组的计算:
array1+1[2,3,4,5,6],array1*array1[1,4,9,16,25]

数组的索引:
和list一样,用方括号和数字array1[1]为2,array2[0][1,2,3]array2[0][1]为2

【pandas】

每次使用前载入,用as取别名方便调用:
import pandas as pd

pandas有两种数据结构,一种是Series,放一维数组,自带数据标签(索引index),一种是DataFrame,放表格式数据,类似excel或者sql的表格,行和列都自带数据标签。注意python是区分大小写的。

Series

生成:

1
2
3
4
5
6
>>>s=pd.Series([1,2,3])
>>>s
>>>0 1
1 2
2 3
dtype=int64

左边的0 1 2即是自动生成的索引,索引名可以自定义,比如将上面的生成Series写成:

1
s=pd.Series([1,2,3],index=['a','b','c'])

那么左边的索引就不是0 1 2而是a b c。

用索引取值的原理和numpy里的array以及python自带的list差不多,都是用方括号,在上面的例子里,

1
2
3
4
5
6
s['a']取1
s['a':'c']取a 1
b 2
c 3
s[['a','c']]取a 1 #注意要嵌套一层方括号
c 3

除了list以外,dict也可以转Series,dict里的key会变成Series里的index。如下:

1
2
3
4
5
6
>>>dict1={'name':'ana','gender':'f'}
>>>s2=pd.Series(dict1)
>>>s2
>>>name ana
gender f
dtype: object

字典转Series也可以自定义index,如果自定义的index比dict里的key有多的,会自动生成空值NaN。接上,如下:

1
2
3
4
5
6
>>>s2=pd.Series(dict1,index=['ana','gender','age'])
>>>s2
>>>name ana
gender f
age NaN
dtype: object

DataFrame

生成
一般是用传入字典的方式:

1
2
3
4
5
6
7
>>>dict2={'name':['ana','bella','cavin'],'gender':['f','f','m']}
>>>df1=pd.DataFrame(dict2)
>>>df1
>>> name gender
0 ana f
2 bella f
3 cavin m

可以看到,DataFrame会自动补充行索引,而列标签则会自动用字典中的key,类似于sql里的column。

查看DataFrame有几行几列何种type有无空值占用内存等信息:
>>>df1.info()

修改
DataFrame的行标签索引无法修改,但可以查看详情:
>>>df1.index
也可以对标签进行重命名:
>>>df1.index=['no1','no2','no3']

列可以修改,修改方式如下:
>>>df1['age']=22,新增一个age列,每行的取值均为22
>>>df1['age']=[21,24,22],修改age列的值,分别赋值为21,24,22
更改列数据类型:
>>>df1.age=df.age.astype('str'),可将age列的数据类型从数值转化为字符串。

选取
选取列:
df1['age']df1.age均可选取age列,输出的是age的所有值和它们对应的索引值。

选取行:
df1[0:1]会切片出表头和索引为0的ana这行
df1[1:2]会切片出表头和索引为1的bella这行
df1.iloc[0]会选取索引为0的ana这行
df1.loc['no1']会选取索引被命名为no1的ana这行

进阶选取:
选取多列:df1[['name','age']],注意要嵌套一层方括号
选取多行:df1[df1.age>22]df1[df1['age']>22]均可表示选取年龄大于22的行
df1[df1.gender=='f']选取性别为女性的行

多条件筛选:
df1[(df1.gender=='f') & (df1.age>23)],注意不能用and``or只能用&``|
这种写法较为复杂,如果条件简单这样写比较直观,但如果条件复杂,就不太清晰。

实现复杂的多条件筛选更常见的是用query,比如上面的筛选用query可以写作:
df1.query('gender=="f" and age>23'),注意在query里是用and or,外面是小括号不是方括号,小括号内用单引号引起来,如果里面有字符串要用双引号。

query可以实现一些相对较为复杂的筛选,比如需要选出大于等于24岁的女性和大于等于22岁的男性时:
df1.query('(gender=="m" and age>=22) or (gender=="f" and age>=24)')

运算
可以直接在列上进行运算,比如:
df1.age=df1.age+1,则所有人年龄增加1

如果是两个DataFrame之间的运算,直接运算会按照同行同列的数字相运算,如果某行列只有一个有取值,会取NaN空值
例如:

1
2
3
4
5
import pandas as pd     #载入pandas包
import numpy as np #载入numpy包
df2=pd.DataFrame(np.arange(4).reshape(2,2),columns=['a','b']) #生成2x2的dataframe,取值0 1 2 3,列名a b
df3=pd.DataFrame(np.arange(6).reshape(2,3),columns=['a','b','c']) #生成2x3的dataframe,取值0-5,列名a b c
df2+df3

输出为:

1
2
3
   a   b    c
0 0 2 NaN
1 5 7 NaN

另一种方法是用加减乘除的函数addsubmuldiv,这样可以指定某个dataframe无取值时的赋值。

1
df2.add(df3,fill_value=0)

此时的输出为:

1
2
3
   a   b    c
0 0 2 2.0
1 5 7 5.0

Credit:这篇study notes是跟着网络教程自学python过程中的学习笔记,网络教程主要来自廖雪峰秦路