一、Python基础语法
1标识符
- 首字母是字母或者下划线
- 其余是字母、下划线、数字
- 大小写敏感
2赋值
- python可以实现多个数值的赋值
a, b = 2, 1.11
print(a)
print(b)
3数据类型
3.1整型
整数类型在32位机器上的取值:-231~231-1
整数类型在64位机器上的取值:-263~263-1
python基本就没有整数类型溢出的问题 了
3.2布尔型
True 是用 1 存储的
False 是用 0 存储的
a = True
b = False
print(int(a)) # 》》1
print(int(b)) # 》》0
3.3浮点型
a = 9.8e3
print(a)
b = -2e-2
print(b)
其中e3就表示103
3.4复数型
a = 2 + 3j
print(a)
print(a.real) #实数部分
print(a.imag) #虚数部分
print(a.conjugate()) #复数a的共轭复数
4包 package
5函数
进制转换
-
十进制转二进制 bin
print(bin(83)) # 这种转换方式前面会带着0b 0b1010011
-
十进制转八进制 oct
# 第一种方式 print(oct(83)) # 0o123 # 第二种方式 print('%o' % 83) #123 # 如果想让第一种方式只输出123 不要前面的0o print(oct(83)[2:]) #123
-
十进制转十六进制 hex
# 第一种方式 print(hex(83)) # 0x53 # 第二种方式 print('%x' % 83) #53
-
二进制转十进制 0b1010
print(0b1010)
-
八进制转十进制 0o1010
print(0o1010)
-
十六进制转十进制 0x1010
print(0x1010)
>>> int(4.5) # 结果向下取整
4
>>> int('123') # 默认为十进制
123
isinstance() 判断某个元素是不是某种类型
a = int(3.14)
isinstance(a, int) #True
map() 映射函数
a = map(str, range(5)) # 生成的是一个str类型的地址
b = map(float, range(9))
print(list(a))
print(tuple(b))
6字典
# 生成所有元素都是3000的字典 --- fromkeys
aDic = {}.fromkeys(('John', 'Rose', 'Jiw', 'SunY'), 3000)
aDic2 = {}.fromkeys(['John', 'Rose', 'Jiw', 'SunY'], 3000)
print(sorted(aDic)) # 这样生成的时候一个列表
# 对于两个列表怎么生成对应的字典? --- zip
names = ['John', 'Rose', 'Jiw', 'SunY']
salaries = [3000, 2000, 1000, 4000]
print(dict(zip(names, salaries))) # 使用zip函数打包,形成一一对应的拉链式的关系
# 对于二级的列表,如何提取【0】号元素作为key,【2】号元素作为value
PList = [('AXP', 'American Express Company', '78.51'),
('BA', 'The Boeing Company', '184.76'),
('CAT', 'Caterpillar', '96.39')]
d = {}
for item in PList:
d[item[0]] = item[2]
print(d)
# 案例一:
names = ['jiwei', 'sunyan', 'liuzixin', 'jihong']
age = [24, 22, 5, 31]
dic = dict(zip(names, age))
print(dic.keys())
print(dic.values())
for i, j in dic.items():
print(i, j)
字典的查找
inf = {'jiwei': 24, 'sunyan': 22}
# print(inf['licai']) # 当查找不存在的元素时 会报错
print(inf.get('licai')) # 使用get方法查找不存在的元素时,不报错,输出None
字典的删除
json文件与字典的关系和转换
一般都是讲字典 转换成json格式,然后发到网页上,
而数据挖掘和分析是将网上的json文件转换成字典格式,再使用Frame或者Series格式去分析。
json格式–>字典;解码
json.load()
字典–>json格式;编码
json.dumps()
import json
x = {'jiwei': 24, 'sunyan': 22, 'john': {'a': 'A', 'b': 22}}
x_encode = json.dumps(x) # 编码
print(x_encode)
print(json.loads(x_encode)) # 解码
7 集合
创建集合
- set()
- frozenset()
集合的运算符
-
in
-
==
-
< 和 >
aSet = set('sunnise') bSet = set('sunset') print('u' in aSet) # 'u'在aSet里面 print(aSet == bSet) # aSet和bSet不相等 print(aSet < bSet) # bSet不包含aSet print(set('sun') < aSet) # set('sun')在aSet里面
-
& 交集
-
| 并集
-
-减
-
^两个集合中不同的元素
aSet = set('sunnise')
bSet = set('sunset')
print(aSet & bSet) # {'u', 'n', 's', 'e'}
print(aSet | bSet) # {'u', 's', 't', 'n', 'i', 'e'}
print(aSet - bSet) # {'i'}
print(aSet ^ bSet) # {'t', 'i'}
集合的函数
- 面向所有集合的函数
aSet = set('sunnise')
bSet = set('sunset')
print(aSet.issubset(bSet)) # 判断aSet是不是bSet的子集
print(aSet.intersection(bSet)) # 交集
print(aSet.difference(bSet)) # aSet与bSet不同的
print(aSet.copy()) # 复制
- 面向可变集合的函数
aSet = set('sunnise')
aSet.add('!') # 添加元素
print(aSet)
aSet.remove('!') # 删除元素
print(aSet)
aSet.update('Yeah') # 用新元素去更新
print(aSet)
aSet.clear() # 清除集合
print(aSet)
Python变量和数据类型
# 使用\对标点"进行转义,若果字符串中出现了'可以使用"去括起来
s = 'Python was started in 1989 by \"Guido\".\n\nPython is free and easy to learn.'
print(s)
# 请把下面的字符串用r'''...'''的形式改写,并用print打印出来:
#
# '\"To be, or not to be\": that is the question.\nWhether it\'s nobler in the mind to suffer.'
s = r'''"To be, or not to be": that is the question.
Whether it's nobler in the mind to suffer.'''
print(s)
# 但是r'...'表示法不能表示多行字符串,也不能表示包含'和 "的字符串
s2 = r'\(~_~)/ \(~_~)/'
print(s2)
# 如果要表示多行字符串,可以用'''...'''表示:但是对于\n这种还是没法转义
s3 = '''Python is created by "Guido".\nIt is free and easy to learn.
Let's start learn Python in imooc!
'''
print(s3)
# 还可以在多行字符串前面添加 r ,把这个多行字符串也变成一个raw字符串:
a = 'python'
print('hello, ', a or 'world')
b = ''
print('hello,', b or 'world')
# 因为Python把0、空字符串''和None看成 False,
# 其他数值和非空字符串都看成 True,所以:
# 1. 在计算 a and b 时,如果 a 是 False,则根据与运算法则,整个结果必定为 False,因此返回 a;
# 如果 a 是 True,则整个计算结果必定取决与 b,因此返回 b。
#
# 2. 在计算 a or b 时,如果 a 是 True,则根据或运算法则,整个计算结果必定为 True,因此返回 a;
# 如果 a 是 False,则整个计算结果必定取决于 b,因此返回 b。
变量作用域
-
全局变量
-
局部变量
如果全局变量和局部变量同名:内层屏蔽外层
a = 3 #全局变量
def f(x):
global a #声明全局变量,才能在里面使用a
print(a) #输出3
a = 5 #局部变量,重新将a赋值为5
print(a + x) #输出13
f(8)
print(a) #a被重新赋值为5
异常(Exception)
try:
num1 = int(input('enter the first number:'))
num2 = int(input('enter the second number:'))
print(num1/num2)
except ValueError: # 当输入的不是int类型的数字时!
print('Please input a digit!')
except ZeroDivisionError as err: # 当输入的第二个数字是0时!
print('The second number cannot be zero!')
print(err) # 打印错误原因
- 当不知道哪里出错,可以使用如下捕获所有异常,一了百了
try:
num1 = int(input('enter the first number:'))
num2 = int(input('enter the second number:'))
print(num1/num2)
except: # 捕获所有的异常;一了百了!
print('Something went wrong!')
- 上面的方法只能判断出错了,但是不知道具体出现什么错误!可以用使用如下方式
try:
num1 = int(input('enter the first number:'))
num2 = int(input('enter the second number:'))
print(num1/num2)
except Exception as err:
print('Something went wrong!')
print(err)
- 异常处理还可以与else语句一起使用;对于多个异常可以如下使用:!!!
try:
num1 = int(input('enter the first number:'))
num2 = int(input('enter the second number:'))
print(num1/num2)
except(ValueError, ZeroDivisionError):
print('Invalid input!')
else:
print('Aha, everthing is OK!')
- 循环,只有当输入格式正确的时候才输出结果,跳出循环
while True:
try:
num1 = int(input('enter the first number:'))
num2 = int(input('enter the second number:'))
print(num1/num2)
break
except ValueError:
print('Please input a digit!')
except ZeroDivisionError:
print('The second number cannot be zero!')
- finally子句
不管出不出错,finally里面的字句都会执行!!!
def finally_test():
try:
num1 = int(input('enter the first number:'))
num2 = int(input('enter the second number:'))
print(num1/num2)
return 1
except Exception as err:
print(err)
return 0
finally:
print('It is a finally clause')
result = finally_test()
print(result)
二、常用标准库函数
re
1re.match
2re.search
3filldall
math
import math
print(dir(math)) # 显示math所包含的函数
# math库函数中包含两个数
print(math.pi) # 3.141592653589793
print(math.e) # 2.718281828459045
print(math.ceil(3.6)) # 向上取整,4
print(math.floor(3.6)) # 向下取整,3
print(math.pow(2, 3)) # 2的3次方,8
print(math.sqrt(4)) # 4开根号,2
print(math.degrees(3.14)) # 将弧度转换成角度179.9087476710785
print(math.radians(180)) # 将角度转换成弧度3.141592653589793
os
import os
print(os.getcwd()) # 获得当前工作目录 C:\python_course\ImoocNanjingUniversity\pythonbase
path = 'G:\\test' # 一个已存在的其他路径
os.chdir(path) # 更改路径为path
print(os.getcwd()) # 查看新的工作路径 G:\test
os.rename('test.txt', 'test1.txt') # 修改文件名
os.remove('test1.txt') # 删除文件
os.listdir(path) # 找到path路径下的所有文件
os.path.join(path, filename) # 将path和filename连接起来
datatime
import datetime
print(dir(datetime)) # 显示datatime里面有哪些函数
from datetime import date
print(date.today()) # 显示今天的日期 2020-05-31
from datetime import time
tm = time(23, 20, 25) # 创建以个23h-20m-25s的时间
print(tm) # 23:20:25
from datetime import datetime
dt = datetime.now() # 获得当前的日期和时间
print(datetime(2020, 5, 31, 20, 16)) # 创建时间
print(dt) # 2020-05-31 20:11:32.771597,其中最后面的是毫秒
# 将时间表示成指定格式的形式
print(dt.strftime('%a, %b %d %Y %H:%M')) # 其中小写a表示简写星期;大写Y表示年的全称
random
import random
print(random.random()) # 随机生成0.0-1.0之间的浮点数
print(random.uniform(1, 5)) # 随机生成1-5之间的浮点数
print(random.randint(1, 5)) # 随机生成1-5之间的随机整数
a = list(range(1, 10))
print(random.choice(a)) # 从列表a中随机选择一个元素
random.shuffle(a) # 随机打乱元素
print(a) # [3, 9, 7, 8, 4, 5, 2, 1, 6]
print(random.sample(range(100), 10)) # 随机截取10个值
print(random.randrange(1, 10)) # 随机选取1-10之间的数
print(random.random(10)) # 随机生成10个随机数
NumPy
ndarray(N维数组)
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(a[0])
print(a[0][0])
print(a[:, [0, 1]]) # 第一行和第二行
print(a[::2]) # 第一行和第三行
print(a[:, ::2]) # 第一列和第三列
print(a[::-1]) # 交换行
print(a[:, ::-1]) # 交换列
import numpy as np
a = np.array([[1, 2], [3, 4], [5, 6]])
b = a.reshape(2, 3) # reshape()函数并不能改变原数组的形状
print(b.shape)
print(a.shape)
a.resize(6, 1) # resize()可以改变a的形状
print(a)
import numpy as np
# 全为1的10*10的数组
x = np.ones((10, 10))
# print(x)
x[1: -1, 1: -1] = 0
print(x)
print('===================================')
# 全为任意值的任意形状的数组
x2 = np.full((10, 10), np.pi, dtype=np.float64)
print(x2)
print('===================================')
# full_like 和 ones_like 和 zeros_like
x3 = np.full_like(x2, 3)
print(x3)
print('===================================')
# 创建单位数组
x4 = np.eye(3)
print(x4)
print('=================================')
print(np.identity(3))
print('=====================================')
# 单位矩阵的对角线 上移(正数)、下移(负数)
print(np.eye(8, k=-2))
# 数组的布尔索引!!!!!!!
import numpy as np
X = np.arange(1, 101)
print(X)
print('===================')
print(X<=50)
print('===================')
print(X[X<=50])
print('=====================')
print(X[(X > 50) & (X % 2 == 0)])
print('=====================')
X[(X > 50) & (X % 2 == 0)] = -1 # 对大于50的偶数 赋值为-1
print(X)
print('======================')
# 对于上述方式修改的是原始数组,使用where修改更常使用,不修改原始数组
print(np.where((X % 2 == 0) & (X > 50), -1, X))
数组的矢量化运算和广播!!!
# 计算每门课程和平均值的差值
import numpy as np
score = np.array([[79, 80, 92], [67, 89, 99]])
mean_score = score.mean(axis=1, keepdims=True) # keepdims表示保持原始的形状(维度),这样在运算的时候就能广播了
print(mean_score)
print(score - mean_score)
Pandas
Series(变长字典)
import numpy as np
import pandas as pd
print(pd.Series([11, 12], index=['北京', '上海']))
print(pd.Series(np.arange(3, 6), index=['A', 'B', 'C']))
print(pd.Series(['jiwei', 'sunyan', 'liuzixin']))
print(pd.Series(np.array([12, 222, 32]), index=['A', 'B', 'C']))
import numpy as np
import pandas as pd
x = pd.Series(np.random.rand(4), index=range(1, 5))
print(x)
print(x.values) # 值;[0.97987755 0.42538069 0.37922368 0.52387939]
print(x.keys()) # 键;RangeIndex(start=1, stop=5, step=1)
print(x[1]) # key为1的这个值,注意不是索引!是字典的key值
print('===================================')
x2 = pd.Series([3, 5, 1, 9], index=['A', 'B', 'C', 'D'])
print(x2['C'])
x2['C'] = 8 # 修改C的值
print(x2)
print(x2[['A', 'B', 'C']])
x2.name = 'Pop'
x2.index.name = 'INDEX'
print('=========================')
print(x2)
print('===================')
print(x+x2)
import pandas as pd
data = {'A': 12, 'B': 22, 'C': 33}
p = pd.Series(data, index=['A', 'B', 'D', 'C'])
print(p)
print(pd.isnull(p)) # 判断是不是空值null
A 12.0
B 22.0
D NaN
C 33.0
dtype: float64
A False
B False
D True
C False
dtype: bool
DataFrame(数据框)
import pandas as pd
data = [['Alex', 10], ['Bob', 20], ['John', 30]]
x = pd.DataFrame(data, columns=['name', 'numbers'], index=range(1, 4))
print(x)
print('=====================================')
data2 = {'state': ['beijing', 'shanghai', 'shenzhen', 'shandong'],
'year': [2001, 2000, 2005, 2010],
'pop': [2.1, 4.2, 1.0, 5]}
x2 = pd.DataFrame(data2)
print(x2)
print('========================================')
data3 = data2
x3 = pd.DataFrame(data3, columns=['year', 'state', 'pop', 'debt'])
print(x3)
print('========================================')
print(x3.columns) # 输出表头
print(x3['state'])
print('=======================================')
import numpy as np
x3['debt'] = np.arange(4)
print(x3)
print('====================================')
data4 = data3
x4 = pd.DataFrame(data4, columns=['state', 'year', 'pop', 'debt'], index=['one', 'two', 'three', 'four'])
x4['debt'] = np.random.rand(4)
print(x4)
# 获得指定的区域,如获得x4的前两行后两列的区域数据
print(x4.iloc[:2, -2:])
# 获得x4中pop最大的值
print(x4['pop'].max())
# 获得x4中pop大于2.5的值
print(x4['pop'] >= '2.5')
print('=================')
# 筛选出pay>=5000的值
for x in frame['pay']:
if int(x) >= 5000:
print(x)
# 筛选出pay>=5000的值 方式二!!!!!
print(frame['pay'] >= 5000)
print((frame['pay'])[frame['pay'] >= 5000])
SciPy
三、数据的获取与表示
1本地数据获取
文件的打开、读写和关闭
文件的打开
- 相对路径
- 绝对路径
f = open('infile.txt') # 当前工作目录下的文件,可以直接打开
f1 = open('G:/3.0 哈尔滨师范大学/MarkDown学习/Python/file.txt') # 其他目录下的文件,需要使用绝对路径
f2 = open('infile.txt', 'w') # 文件以写的方式打开,默认值为r 读
f3 = open('outfile.txt', 'wb', 0) # 第三个参数表示缓冲区大小,默认为-1,(0代表不缓冲,1或者大于1表示缓冲一行或指定缓冲区大小)
f4 = open('infile.txt', 'rb', encoding='UTF-8') # 第四个参数表示编码格式
文件格式
-
r:读文件模式,文件必须存在
-
w:写文件模式,清空文件内容或者是新建一个文件
-
a:追加,在文件的尾部加内容
-
r+ = r + w 读写模式
-
w+ = w + r 读写模式(清空原内容)
-
a+ = a + r 读和追加模式
-
rb : rb+ 后面加b就表示二进制文件的读写和追加
-
wb :wb+
-
ab:ab+
文件相关函数
open()函数返回一个文件file对象 f = open(‘file.txt’, rw)
对象名.方法名
- f.read() 将文件内全部数据读出来作为一个字符串返回
with open('infile.txt') as f:
print(f.read(5)) # 注意!!!读文件的指针到哪,下一次读取就接着读取
print(f.read())
- f.write()
下面的写法并不推荐
f = open('infile.txt', 'w')
f.write('Hello World !')
f.close()
正常应该以下面的写法去操作
with open('infile.txt', 'w') as f:
f.write('Hello!')
-
f.readline() 读取一行数据
-
f.readlines() 读取多行数据,返回的是一个列表
-
f.writelines() 写入多行数据
with open('infile.txt') as f1:
data = f1.readlines()
for i in range(len(data)):
data[i] = str(i+1)+''+data[i]
with open('outfile.txt', 'w') as f2:
f2.writelines(data)
- f.close() 关闭文件对象
当使用with open() as f:语句就不用每次都关闭文件对象了!
- f.seek()
s = 'Tencent Technology Company Limited'
with open('outfile.txt', 'a+') as f:
f.writelines('\n')
f.writelines(s)
f.seek(0) # 将文件指针放回文件开头位置
print(f.readlines())
小案例:查看文件有几行
try:
with open('infile.txt') as f:
data = f.readlines()
except FileNotFoundError:
print('file not find!')
lens = len(data)
print('file has {} lines.'.format(lens))
和os库结合起来使用
import os
def countLines(fname): # 以文件名作为参数传入
try:
with open(fname) as f:
data = f.readlines()
except FileNotFoundError:
print('not found file')
lens = len(data)
print(fname.split('\\')[1] + 'has' + str(lens) + 'lines')
path = 'C:/python_course/ImoocNanjingUniversity/pythonbase'
# os.listdir()找到当前path路径目录下的所有文件
for fname in os.listdir(path):
# 如果文件名以.txt结尾
if fname.endswith('.txt'):
# 将路径和文件名连接起来
file_path = os.path.join(path, fname)
# 调用函数
countLines(file_path)
2网络数据获取
- 网络数据如何获取?(爬虫)
- 抓取 requests库
- 解析 bs4库的BeautifulSoup
-
如何查看网页能不能被爬取呢?
这个时候可以在网站的后面加上robots.txt如果可以访问就是可以爬取的
例如https://blog.csdn.net/robots.txt
requests库
import requests
r = requests.get('https://blog.csdn.net/')
print(r.status_code) # 200表示正常
print(r.text)
BeautifulSoup库
此时注意!!!解析的时候必须要有lxml解释器
不然会报错bs4.FeatureNotFound: Couldn’t find a tree builder with the features you requested: lxml. Do you need to install a parser library
可以安装lxml库,解决问题。
from bs4 import BeautifulSoup
markup = '<p class="title"><b>The Little Prince</b></p>'
soup = BeautifulSoup(markup, features='lxml')
print(soup.b) # <b>The Little Prince</b>
print(type(soup.b)) # <class 'bs4.element.Tag'>
tag = soup.p
print(tag.name) # p
print(soup.find_all('b')) # [<b>The Little Prince</b>]
综合起来使用实例
import requests
from bs4 import BeautifulSoup
r = requests.get('https://image.baidu.com/search/index?isource=infinity&iname=baidu&tn=baiduimage&word=caizhuoyan')
soup = BeautifulSoup(r.text, 'lxml')
pattern = soup.find_all('p')
print(pattern)
3拓展学习
正则表达式
正则表达式验证的网站:
www.regex101.com
输入和输出
1如何输入获得多个字符串?
- 字符串格式
# 默认是使用空格分隔的!
x, y = input('input:').split()
print('x:', x)
print('y:', y)
# 使用其他字符分隔
a, b = input('input:').split(',')
print('a:{}, b:{}'.format(a, b))
2如何输入获得两个整数?
- 整数类型
# 注意这个时候的输入应该用 , 分隔
# 注意输入必须为数值类型
x, y, z = eval(input('input:'))
print('x:{}, y:{}, z:{}'.format(x, y, z))
3如何输入一个元素后获得一个元素均为数值型的列表?
st = list(eval(input('input:'))) # input:1,2,3,11,22
print(st) # [1, 2, 3, 11, 22]
st2 = eval(input('input:')) # input:[1, 3, 444, 11]
print(st2) # [1, 3, 444, 11]
4多个元素输出,以逗号分隔开
# 输出的时候使用sep作为多个输出的分隔
x, y, z = 1, 3, 'a'
print(x, y, z, sep=',') # 1,3,a
5对于循环中的输出,将所有输出数据放在一行输出
for i in range(10):
print(i, end=',')
列表解析
data = input('input:').split(',') # input:11,22,as,l
print(data) # ['11', '22', 'as', 'l']
print([eval(i) for i in data]) # 列表解析 将字符串转换成数值类型 输入必须都为数值才行
函数式编程
函数式编程完场上面的列表解析
data = input('input:').split(',')
print(list(map(eval, data)))
主要由3个基本函数和1个算子构成
- map()函数
lst = [2, 1, 8, 9]
print(list(map(lambda x: x*2, lst)))
# 把数值转换成字符串
data = list(range(10))
print(list(map(str, data)))
# 把字符串全都改成大写
data2 = ['asd', 'open', 'hello', 'python']
print(list(map(lambda x: x.upper(), data2)))
- filter()函数
lst2 = [1, 2, 3, 4, 5, 6]
print(list(filter(lambda x: x % 2 == 0, lst2)))
- reduce()函数
from functools import reduce
lst3 = [1, 2, 3, 4, 5]
print(reduce(lambda x, y: x + y, lst3))
- 算子(operator):lambda
浅拷贝和深拷贝
- 赋值如x = [1, 2, 3] y = x 表示x和y共用一块内存地址
a = [1, 2, 3, [4, 4]]
b = a
a[0], a[3][1] = 9, 9
print(a) # [9, 2, 3, [4, 9]]
print(b) # [9, 2, 3, [4, 9]]
- 浅拷贝:只复制了父对象,而不复制内部子对象;copy()
a = [1, 2, 3, [4, 4]]
c = a.copy()
a[0], a[3][0] = 9, 9
print(a) # [9, 2, 3, [9, 4]]
print(c) # [1, 2, 3, [9, 4]]
- 深拷贝:不仅复制父对象,而且复制内部子对象;copy.deepcopy()
import copy
a = [1, 2, 3, [4, 4]]
d = copy.deepcopy(a)
a[0], a[3][0] = 9, 9
print(a) # [9, 2, 3, [9, 4]]
print(d) # [1, 2, 3, [4, 4]]