-
python學習
- DAY01-DAY04基礎操作
- DAY05-DAY09基本模塊
常用pip源
(1)阿里云
http://mirrors.aliyun.com/pypi/simple/(2)豆瓣
http://pypi.douban.com/simple/(3)清華大學
https://pypi.tuna.tsinghua.edu.cn/simple/(4)中國科學技術大學
http://pypi.mirrors.ustc.edu.cn/simple/(5)華中科技大學
http://pypi.hustunique.com/
第一講
基礎知識
# ctrl+/ 添加注釋
# ctrl+alt+l 三鍵實作格式規范
# 或者在pycharm編譯器中點擊“code->Reformat Code
# 英文輸入符號
# \+特定字符 產生一個新的含義,就是轉義字符(# \\ \t)
print(666)
print('我愛編程')
# sep=','指定,為分隔變數的符號
print('唐三', '小舞', '張三', sep=',')
print('唐三', '小舞', sep='\n')
# end='\n'指定換行結尾
print('唐三', '小舞', end='*')
print('唐三', '小舞', end='\n')
# 變數
# 1.有一定意義
# 2.由數字,字母,下劃線組成,數字不能開頭
name = '張三'#等號是賦值
print(name)
# input()表示輸入,在括號里面加入''可加入提示
input('請輸入您的密碼')
第二講
資料型別
# 整型 int
# 浮點型 float
# 字符型 str
# '''中間可以放幾段話'''
name = '''
啦啦啦
啦啦啦
啦啦啦
'''
print(name)
# type函式
name = '漩渦鳴人'
print(type(name))
# 運算注意優先級以及從左向右計算
# 字符不能和整數型別相加,但可以變換
name = '張三'
age = 48
print(name + str(age))
# 同理整型和浮點型別也可以相互轉換,但有非數字的字符不能轉換為整數,也不能是浮點型別結構
第三講
運算子
# + - * / % 加減乘除求余
number = input('請輸入數字')
number = int(number) # 輸入的是字符型別,用int轉換為整數型別進行運算
result = number % 2
print(result)
# //表示整除運算
bounty = 5000
print(bounty/280) # 結果是17.86
print(bounty//280) # 結果是17
# += *= /= -= 運算子
# 關系運算子回傳值型別是布爾型別
# ord()函式可以查看字符對應的整數數值
print(ord('a'))
# 邏輯運算子 and or not
# and 有假就為假 or 有真就為真 not 真就假假就真
第四講
條件陳述句
- if陳述句的使用
- if…else陳述句的使用
- 多重if陳述句的使用
- if嵌套
# if 要判斷的條件: (標準結構)
# 條件成立時要做的事情
# else:
# 條件成立時要做的事情
money = input('請輸入您的錢數')
money = int(money) # 注意轉換
things1 = '盲盒'
if money>35:
print('拿下{}'.format(things1))
# 用{}進行占位,用.format()函式填充占位
else:
print('買不起')
# elif陳述句
# if 條件1:
# 事情1
# elif 條件2:
# 事情2
# else:
# 事情3
choice1 = input('請輸入你要選的品牌')
choice2 = input('請輸入你要選的衣服型別')
money = input('請輸入你手中有多少錢')
money = int(money)
if choice1 == '安踏' and choice2 == '短袖' and money > 60 :
print('您購買了{}品牌的{}'.format(choice1,choice2), '您還有{}元錢'.format(money-60) , sep = '\n')
elif choice1 == '李寧' and choice2 == '短袖' and money > 60 :
print('您購買了{}品牌的{}'.format(choice1,choice2), '您還有{}元錢'.format(money-60) , sep = '\n')
elif choice1 == '耐克' and choice2 == '短袖' and money > 60:
print('您購買了{}品牌的{}'.format(choice1, choice2), '您還有{}元錢'.format(money - 60), sep='\n')
else:
print('您要的我們沒有或者您的錢不足以支付請重試')
# if下陳述句可繼續嵌套if
第五講
回圈陳述句
- while的使用
- for的使用
- break和continue的使用
- while或者for與else結合使用
回圈的核心在于減少重復代碼,條件要盡量通用化
# while 回圈條件:(當回圈條件不成立時結束)
# 回圈執行的代碼
i = input('請輸入數字')
i = int(i)
while i <= 5:
i += 1
print(i)
# 需求:限制登陸次數
i = 3
while i >= 1:
username = input('請輸入用戶名')
password = input('請輸入密碼')
if username == 'admin' and password == '123456' :
print('登錄成功')
break # 作用在于登錄成功后退出回圈
else:
print('登錄失敗')
i -= 1
print('還有{}次機會' .format(i))
continue # 繼續回圈
# for 變數 in 序列:
# 回圈體
# 變數:自定義變數名,要求和單獨定義時候一樣
# 序列:容器型資料型別的資料,比如字串,布爾,串列,元組,集合
# 回圈體:需要重復執行的代碼
for x in range(1,11):
print('今天你直播下單{}次'.format(x))
# range()函式作用是產生一個序列,從0開始
# range(1,11)則表示從1開始11結束但是不包括11
# range(1,6,2)表示135的序列,即2為步長(可以是負數)
# 需求:限制登陸次數
for i in range(3):
username = input('請輸入用戶名')
password = input('請輸入密碼')
if username == 'admin' and password == '123456' :
print('登錄成功')
break # 作用在于登錄成功后退出回圈
else:
print('登錄失敗')
print('還有{}次機會' .format(2-i))
continue # 繼續回圈
# continue 跳過本次回圈,后面陳述句不執行,繼續執行下一次回圈
# 需求:列印1-12數字,除了8不列印
# 方法一
for i in range(1,13):
if i == 8:
continue
else:
print(i)
# 方法二
i = 1
while i <12:
i += 1
if i == 8 :
continue
print(i)
# else可以和while,for進行配合
# 案例一
i = 13
while i <12:
print('驗證失敗')
else:
print('驗證成功')
# 案例二
for i in range(8):
print(i , end=' ')
else:
print('\n')
print('結束')
第六講
資料型別串列(串列類似陣列,字典類似結構體)
- 串列的使用
- 字典的使用
- 字串的使用
# 以前介紹的int bool str float都只能存放一個值,需要串列存放一堆值
# 變數名字 = [元素,元素,元素]
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(type(heros))
輸出結果是<class ‘list’>,即構成了一種新的資料型別串列
# 那怎么找到串列中的某一個元素呢?這就要用到串列索引
# 計算機編號從0開始,相關方式類比陣列
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(heros[1])
即可獲取張四,同理可以獲取其他元素,若要同時獲取多個元素,則要使用串列切片的辦法
# 1:3表示索引的一個左閉右開區間,只包含左邊不包含右邊
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(heros[0:6])
# [3:]若省去終止位置,則表示從標明的初始位置一直索引到終止位置
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(heros[0:])
這樣就可以把上述元素全部輸出出來了(倆個方法結果一樣)
輸出結果為 [‘張三’, ‘張四’, ‘張五’, ‘張六’, ‘張七’, ‘張八’]
但是顯然不可能所有的取法步長都為一也不可能都是順序取元素
# 完整格式 print(串列名(初始位置:終止位置:步長)) 默認步長為+1
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(heros[0::2])
這樣就可以輸出從第一個元素開始的所有奇數項元素
我們在長資料超大資料時,往往不方便一次看出到底有多少個元素
# len()函式可以獲取串列的長度
print(len(heros))
我們往往需要增加洗掉修改查找串列元素,實作串列元素動態管理
(增刪改查)
增
# append可以實作串列元素增加
heros.append('張九')
# insert函式可以定向添加元素
# insert方法只是插入元素,原來在此位置以及之后的元素全體后移
heros.insert(3, '張六plus')
刪
# pop或者remove可以實作串列元素洗掉
# 串列.pop[索引]表示洗掉特定位置索引位置的元素
heros.pop() # 若索引為空表示洗掉最后一個元素
heros.remove('張三') # 移除張三這個元素
改
heros[0] = '張三plus' # 實作修改定向位置的元素
查
# index函式可以實作查找某一元素具體位置,并通過變數存盤,在案例實作的時候有奇效
number1 = heros.index('張三')
print(number1)
# 可以利用 in 來判斷元素在不在串列內
# 格式 查找的元素 in 串列名 回傳值是布爾型別,可以用int轉換后用變數儲存下來
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
number3 = int('張2' in heros)
print(number3)
# index 和 in 可以相互補充相互協調,index回傳具體位置,in判斷在不在,還可以配合后面的count來判斷在不在
有些時候一個串列會有很多重復的元素,我們需要函式來幫我們進行計數
# 串列名.count(要查詢的元素) 回傳值為元素個數
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
heros.append('張三')
heros.append('張三')
heros.append('張三')
heros.append('張三')
number2 = heros.count('張三')
print(number2)
字典
# 基礎格式 變數名字 = {key1:value1,key2:value2}
hero = {'姓名': '孫悟空','性別': '男', '定位':'戰士' }
print(hero)
print(type(hero))
得到的結果是<class ‘dict’>即構成了一種新的資料型別串列
字典還可以和串列搭配使用
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
print(hero)
print(type(hero))
# 那如何獲取里面中的東西呢
print(hero['性別'])
# 如何判斷字典里面是否有我們查找的鍵呢
# print(字典名.get(查找的鍵,如果找不到回傳的東西))
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
print(hero.get('定位', '未知'))
# 我們用get的時候,如果鍵存在則回傳鍵的值,如果鍵不存在則回傳設定的回傳值,如果我們沒有設定回傳值,則回傳NONE
字典同樣支持增刪改查操作,實作動態管理
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
hero['血量'] = 4399 # 對于一個原來沒有的鍵進行操作會添加
hero['性別'] = '未知' # 對于一個原來有的鍵進行操作會修改
print(hero)
# 字典名.pop[鍵名]表示洗掉特定鍵
heros.pop('定位')
# 可以利用 in 來判斷元素在不在字典內
# 格式 查找的鍵 in 字典 回傳值是布爾型別,可以用int轉換后用變數儲存下來
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
number4 = int('姓名' in hero)
print(number4)
# value函式可以輸出字典的所有值
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
print(hero.values())
# 結果為: dict_values(['孫悟空', '男', '戰士', ['八戒', '沙僧', '唐僧']])
# value的作用不光只是顯示,還可以配合in進行邏輯判斷
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
print(int('孫尚香' in hero.values())) # 回傳值為布爾型別
字串的使用
# 單引號,雙引號,三引號三種宣告方式,三引號的優點在于可以原樣輸出,空格空行都會被保留
hero1 = 'hello'
hero2 = "hi"
hero3 = '''
hello
hi
'''
print(hero1, hero2, hero3)
字串和串列一樣,也有切片和索引的訪問形式
把字串當成字符的串列
message = '王者榮耀'
print(message[0])
print(message[:2]) # 從初始位置到2這個位置
# 案例 在任意一個輸入字串中,查找是否有英雄這個子串
string = input('請輸入一個字串')
lenstr = int(len(string))
for x in range(0, lenstr):
if string.find('英雄') >= 0:
# find函式可以查找,如果找到顯示第一個字符的位置,如果沒找到會回傳-1
print('有英雄這個子串')
break
else:
if x == lenstr - 1 :
print('沒有英雄這個子串')
else:
continue
print(string.startswith('王者'))
print(string.endswith('王者'))
# startswitch函式可以判斷是否以某某字符或字串開頭,回傳值為布爾型別
# endswitch函式可以判斷是否以某某字符或字串結尾,回傳值為布爾型別
簡化字串技巧
字串中有很多空格或者轉義字符我們可以用一個函式全部去除
# strip函式
s = ' hello\\\\\mm\n\n\n\n'
print(s.strip())
輸出結果是 hello\\mm
第七講
函式
- 函式的作用與定義
- 函式的引數
- 函式的回傳值
# 函式格式(定義)
def sum(num):
# def關鍵字表示定義一個函式 sum是函式名 num是形參可以有多個
result = 0
for x in range(1, num+1):
result += x
print(result)
# 要注意縮進,以及分號的使用
# 函式呼叫
# 呼叫格式: 函式名(引數)這里引數是實參
def sum(num):
result = 0
for x in range(1, num+1):
result += x
print(result)
number = 1
sum(number)
案例
定義一個函式來實作用戶的登錄
def login():
username = input('輸入用戶名')
password = input('輸入密碼')
if username == 'admin' and password == '123456':
print('登錄成功')
else:
print('登錄失敗')
login()
函式的引數
# 有參傳參,無參空著,順序一致
def milk_tea(n,kind='波霸奶茶'): # n表示奶茶數量,kind表示奶茶種類
# 默認引數一定要在普通引數后,默認引數可以不傳參使用默認值
# 可以有很多默認引數但一定要在所有普通引數結束后再寫默認引數
for i in range(n):
print('正在制作第{}杯奶茶'.format(i+1))
print('放入{}的原材料'.format(kind))
print('調制奶茶')
print('倒入奶茶')
print('封口')
milk_tea(5)
milk_tea(1, '珍珠奶茶')
milk_tea(4, '椰果奶茶')
milk_tea(5, '黑糖珍珠奶綠')
關鍵字引數
def milk_tea(n, kind='波霸奶茶',price=15): # n表示奶茶數量,kind表示奶茶種類
print('顧客您需要的{},每杯{}元,應收{}元'.format(kind,price,n*price))
for i in range(n):
print('正在制作第{}杯奶茶'.format(i+1))
print('放入{}的原材料'.format(kind))
print('調制奶茶')
print('倒入奶茶')
print('封口')
milk_tea(1)
milk_tea(2, '原味奶茶')
milk_tea(n=4, kind='原味奶茶',price=18) # 關鍵字引數可以自定義傳輸
回傳值
# 計算從1到num的和
def ger_sum(num):
sum = 0
for i in range(num):
sum += i+1
return sum
num1 = input('請輸入要計算到的數字')
num1 = int(num1)
result = ger_sum(num1)
print('result = {}'.format(result))
第八講
面向物件基礎
一類人或一類車等的定義方法用串列太過復雜,所以抽象出類這一概念
面向程序編程(把大象放進冰箱需要幾步)
- 把冰箱門打開
- 把大象裝進去
- 把冰箱門關上
面向物件編程(大象,冰箱的種類,具象化目標具象化實作)
類的定義
# class 類名:
# 屬性
# 方法
要求
-
類的首字母必須大寫
-
類名后面必須有冒號
-
類體有縮進
class Phone:
pass
# 在python中 pass是空陳述句,是為了保持程式結構的完整性,pass不做任何事情,一般用于占位有陳述句,支撐結構
class Phone:
brand = '華為'
color = '黑色'
type = 'Mate30 pro'
price = 9999
# 定義行為和函式相似,只是必須帶上一個引數self
def call(self):
print('打電話')
def send_message(self):
print('可以發資訊')
class Saiya:
name = '悟空'
hair = '固定'
has_tail = True
appetite = '大'
def fight(self):
print('我們賽亞人就是喜歡戰爭')
類的使用
類的定義主要用途是把一個類的所有特征抽象出來,而用到具體物件時則需要講抽象的特征一一賦值一一對應
# 物件名 = 類名(引數),其中引數是可選引數,可有可無
phone1 = Phone()
phone2 = Phone()
phone3 = Phone()
print(phone1)
print(phone2)
print(phone3)
# 訪問方式 物件名.屬性名 or 物件名.方法名
print(phone1.price)
屬性添加的方式
- 通過外層的物件動態添加
- 使用建構式添加
# 通過外層的物件動態添加
phone1.price = 10000
print(phone1.price)
# __init__魔術構造方法也就是建構式,會在開始時自動呼叫
class Person:
country = '中國'
def __init__(self,name):
# self表示物件本身,self.name = name表示在當前物件中增加一個屬性并且賦值(在這里也就是Person)
print('我是一個__init__方法')
self.name =name
def eat(self):
print('我是一個吃貨')
p1 = Person(name = '龜龜')
p2 = Person(name = '兔兔')
print(p1)
print(p2)
類的方法的定義與呼叫
class Person:
name = '悟空'
def __init__(self,name):
self.name =name
def eat(self):
print('我是一個吃貨')
def sprot(self, time):
if time < 6:
print(self.name + '你怎么這么勤快,這么早就起床了')
else:
print(self.name + '怎么這么愛睡懶覺!')
self.eat()
p1 = Person(name = '龜龜')
p2 = Person(name = '兔兔')
p1.sprot(time=3)
p2.sprot(time=7)
類的繼承
class Saiya:
def __init__(self,name):
self.name = name
def eat(self):
print(self.name + '我是一個吃貨')
def sprot(self, time):
if time < 6:
print(self.name + '你怎么這么勤快,這么早就起床了')
else:
print(self.name + '怎么這么愛睡懶覺!')
self.eat()
# 假設有另外一類人的定義,和上面Person幾乎一樣,為了減少代碼重復,引入繼承
class Saiya(Person):
#這樣就可以表示Saiya類繼承了所有Person屬性和行為(可以任意呼叫Python),這樣我們就有更多的代碼空間進行Saiya不同于Person的特性,大大簡化了代碼
第九講
模塊(python的魔法棒)
- 模塊簡介
- 模塊匯入
- 包的匯入
- 模塊搜索路徑
- __name__的使用
- 常見系統模塊介紹
# 創建模塊的本質就是創建一個.py檔案,它可以被其他模塊匯入并使用
# 呼叫模塊的方法
# import
# from ... import
# 模塊命名要用小寫字母,且不要和內置模塊重名
創建一個.py檔案(harry.py)
# harry.py
name = 'Harry Potter'
age = 10
def Fight(tool=None):
if tool:
print('在魔法學校駕駛' + tool + '練習飛行')
else:
print('走到魔法學校就會練習飛行了!')
class Course:
def __init__(self,name,c_list=[]):
self.name = name
self.c_list = []
def add_course(self,c_name):
if c_name:
self.c_list.append(c_name)
else:
print('選修課不能為空')
def remove_course(self,c_name):
if c_name:
self.c_list.remove(c_name)
else:
print('選修課不能為空')
再創建一個magic.py檔案
# magic.py
def use_magic():
print('我會施展厲害的魔法')
此時兩個模塊已經封裝完畢,我們只需要import 模塊名即可呼叫模塊里面的函式變數以及類,我們的使用方式主要是通過點運算子來完成的
# 在包檔案中進行呼叫(一般匯入陳述句都在開頭)
import harry
import magic
print(harry.name)
harry.Fight()
c = harry.Course('哈利')
c.add_course('黑魔法防御術')
magic.use_magic()
# 模塊重命名
import harry as hy # 這樣防止模塊名字太長起到重命名的作用
# 匯入方法2
from harry import name
from harry import Fight
from harry import Course
print(name)
Fight()
c = Course('哈利')
c.add_course('黑魔法防御術')
# 這種方法就不用使用harry.的方法,相當于提前宣告來源,簡化邏輯,也可以起到引入特定變數特定函式特點類的作用
# from harry import name
# from harry import Fight
# from harry import Course
也可以用以下表達代替用來簡化代碼
from harry import name, fight, Course
或者
from harry import *
# 這個表示把所有的都匯入
匯入模塊從本質上來說就是去執行一個.py檔案,開辟一個新記憶體,把匯入的東西放進記憶體中,這樣我們呼叫就可以直接從記憶體中獲取,當模塊數量越來越多時,我們就需要通過包的形式對模塊進行管理
包就是一個包含__init__.py的檔案夾
# 創建一個包(包的命名規則與模塊相同)
# 右鍵點擊new,然后創建python package
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2wsqM5f0-1630476391786)(C:\Users\dell\Desktop\QQ截圖20210813172613.png)]
# 創建好以后將之前封裝好的harry.py和magic.py拖到包中檔案夾
包的匯入
# 拖入后我們可以看到原來的匯入格式被修改了
from package.harry import *
# 編譯器自動維護了package.的格式表明路徑
import sys
print(sys.path)
# 利用sys包我們可以查找我們當前腳本檔案的位置
# 在新創建的包檔案中創建magic1,magic2,text的.py檔案
magic1.py
def use_magic():
print('我會施展最厲害的魔法')
print('我是一個新的magic模塊' + __name__)
text.py
from package.harry import *
from package.magic1 import use_magic
# __name__的用途在于,如果在它原本的模塊運行,輸出為__main__在別的模塊運行則輸出為路徑,可以利用這一性質,來實作一些陳述句只模塊內輸出而不模塊外輸出
magic.py
def use_magic():
print('我會施展最厲害的魔法')
if __name__ == '__main__':
print('我是一個新的magic模塊' + __name__)
這樣'我是一個新的magic模塊'這個陳述句就不會被誤輸出了!妙啊
系統內置模塊
-
# time模塊 # 可以獲取當前的時間戳 import time t1 = time.time() print(time.ctime(t1)) # 利用sleep函式進行每隔一秒回圈進行一次 import time for i in range(5): print(i) time.sleep(1) # datetime # datetime中封裝了date,time,datetime,timedelta其中timedelta是值時間差 from datetime import * print(datetime.now()) dt = datetime.now() dt1 = dt + timedelta(days=-1) # 表示日期-1 print(dt, dt1, sep='\n') -
# random模塊 import random print(random.random()) # 表示從0到1的隨機小書 print(random.randint(1, 10)) # 表示從1到10的隨機整數(包括1和10) print(random.randrange(1, 10)) # 表示從1到10的隨機整數(不包括10) print(random.choice(range(10))) # random.choice(串列或資料集),表示從串列或資料集中隨機獲取一個元素,起到定范圍而又隨機的作用 -
# os模塊 import os # 查看當前作業目錄 result1 = os.getcwd() print(result1) # 在當前檔案夾中創建一個檔案夾 # os.mkdir()只能創建一級目錄,而os.makedirs()可以創建多級目錄, os.mkdir('images') # 獲取當前環境變數 print(os.environ) # 獲取絕對路徑 result = os.path.abspath('harry.py') print(result) # os.listdir('package')查看檔案串列 # os.remove('package/text.py')洗掉某個模塊 注意以下操作只能針對同級或下級檔案,如harry.py中使用下面代碼則會報錯,一定要在與package同級的.py檔案中操作才有用 result = os.listdir('package') print(result) os.remove('package/text.py') # 查看檔案大小 path = './package/harry.py' # .表示當前目錄下 result = os.path.getsize(path) print(result) # 查看是否為檔案 result1 = os.path.isfile('path') print(result1) # 查看是否為檔案夾 result1 = os.path.isdir('path') print(result1)
第十講
python的檔案操作(自動化記錄)
- 檔案寫入
- 檔案讀取
- csv檔案的寫入
- csv檔案的讀取
# open()函式的使用,open函式的作用是打開一個檔案并且有回傳值(布爾型別)
# 檔案要素:存放位置,檔案名字
# 相對位置 ./main.py同一目錄下的檔案表示
# 絕對路徑 D://user/hello/main.py
stream = open(file='./666') # 變數stream起到了傳輸管道的作用
print(stream)
輸出結果為<_io.TextIOWrapper name=’./666’ mode=‘r’ encoding=‘cp936’>
mode = 'r’讀操作,'w’寫操作,'a’追加,'t’文本格式,'b’位元組方式讀取且這些字母可以組合使用
encoding表示編碼集即翻譯方式
# mode,encoding可以修改
stream = open(file='./666', mode='w')
print(stream)
stream = open(file='./666', mode='w', encoding='utf-8')
print(stream)
檔案寫入以及關閉
stream = open(file='./666', mode='w', encoding='utf-8')
print(stream)
record = '4月18日 17:00 FPX PK RNG'
stream.write(record) # 檔案寫入
stream.close() # 檔案關閉 一定要關閉涉及資料安全
# 如果打開的檔案不存在,則會新建一個檔案
stream = open(file='./text1.txt', mode='w', encoding='utf-8')
print(stream)
# 將mode改成a即可實作不斷追加,但追加并不會幫我們換行,所以當我們需要換行的時候需要在加入的文本前用換行符號
stream = open(file='./text1.txt', mode='a', encoding='utf-8')
print(stream)
record = '\n4月18日 17:00 FPX PK RNG'
stream.write(record) # 檔案寫入
stream.close()
那如果資料量很大怎么辦呢
record = ['4月1日 17:00 IG PK RA',
'4月2日 17:00 LGD PK SN',
'4月3日 17:00 FPX PK RA',
'4月4日 17:00 SN PK WE',
'4月5日 17:00 JDG PK FPX',
'4月6日 17:00 SN PK TEX'
]
stream = open('records.txt',mode='w',encoding='utf-8')
for record1 in record: # 通過回圈來進行寫入并在后面添加換行符號
stream.write(record1 + '\n')
stream.close()
stream = open('records.txt',mode='a',encoding='utf-8')
# 再次寫入的時候格式要變成a,并且重新打開
stream.write('123456')
stream.close()
# 寫入后一定要關閉檔案
那檔案的讀取改如何操作
stream = open('records.txt', mode='r', encoding='utf-8')
# 讀取中格式為r
content = stream.read()
# 用一個變數保存我們閱讀的值
print(content)
stream.close()
# 讀格式和寫格式有所不同,當寫格式檔案不存在的時候會創建一個檔案,而讀取一個不存在的檔案則會報錯
檔案的例外處理(處理報錯情況)
-
# 格式 try: 可能會有例外的代碼 except: 發生例外的時候要執行的代碼 finally: 無論是否有例外都要執行的代碼 -
# 方法1 content = None try: stream = open('records.txt', mode='r', encoding='utf-8') content = stream.read() except: print('檔案找不到') finally: print(content) # 這段代碼邏輯就是,設定變數為空,如果檔案可以找到并打開,將改空代碼重新賦值并且輸出,如果檔案無法找到并打開,則會輸出except的提示陳述句,并且輸出空,這樣就可以避免了報錯導致程式例外終止 -
# with關鍵字的使用 with 運算式 as 變數: 陳述句 -
with open('records.txt',mode='r',encoding='utf-8') as stream: content = stream.read() print(content)
csv檔案的操作
csv檔案是以逗號隔開的
import csvrecord = [['4月1日 17:00 IG PK RA'], ['4月2日 17:00 LGD PK SN'], ['4月3日 17:00 FPX PK RA'], ['4月4日 17:00 SN PK WE'], ['4月5日 17:00 JDG PK FPX'], ['4月6日 17:00 SN PK TEX']]with open('electronic_sport.csv', 'w', encoding='utf_8') as stream: writer = csv.writer(stream) writer.writerow(['date', 'time','adversary']) for recod in record: writer.writerow(recod) # 也可以直接用writer.writerows來實作多行同時寫入
檔案寫入不同作業系統的展示結果不同,windows常會附加空行
如有需要改變可以open(‘electronic_sport.csv’, ‘w’, encoding=‘utf_8’,newline = ‘’ )
csv檔案的讀取
with open('electronic_sport.csv', mode='r', encoding='utf-8') as stream: reader = csv.reader(stream) for row in reader: print(row)
第十一講
Pillow圖片處理
PIL是python中一個強大而方便的影像處理庫,Pillow是PIL的一個分支,我們在安裝的時候盡量安裝pillow,PIL和pillow不能共存,記得先卸載PIL哦!
如果遇到問題解決網址
Pycharm無法用pip安裝PIL以及安裝Pillow之后依然報錯“No module named ‘Pillow’”的詭異問題_清水河C羅——Leonardo-Liu-CSDN博客
- Image模塊的使用
- 其他模塊的使用
- ImageDraw
- ImageFont
- ImageFilter
# open()
# new()
# convert()
# 呼叫與展示
import PIL
from PIL import Image
image = Image.open(fp='證件照.jpg')
image.show()
# 注意圖片要手動關閉,不然會占用程式行程
圖片屬性
print(image.size) # 大小回傳一個二維坐標
print(image.mode) # 回傳影像渲染模式RGB等
print(image.format) # 回傳格式
# 如果不是本地檔案則無法讀取格式
convert函式
# convert函式可以改變影像渲染格式,1是一種渲染方式
image1 = image.convert('1')
image1.show()
| mode | 描述 |
|---|---|
| 1 | 1位像素,黑白,每位元組存盤一個像素 |
| L | 8位像素,黑白 |
| P | 8位像素,使用調色板映射到任何其他模式 |
| RBG | 3×8位像素,真彩 |
| RBGA | 4×8位像素,帶透明蒙版真彩 |
| CMYK | 4×8位像素,分色 |
| YCbCr | 3×8位像素,彩色視頻格式 |
| LAB | 3×8位像素,Lab顏色空間 |
| HSV | 3×8位像素,色相,飽和度,值顏色空間 |
| I | 32位有符號整數像素 |
| F | 32位浮點像素 |
RGB是指色彩顏色的組合,R代表紅,G代表綠,B代表藍,就是紅綠藍的組合每個顏色值都可以在0到255取值,即用0到255量化各顏色的比例
構造新影像
image = Image.new('RGB', (220, 150), (150, 150, 255))
# new函式可以生成一個新影像,第一個是影像渲染方式,第二個是影像大小,第三個是你選中的影像渲染方式的引數,我們這里是RGB,所以填的數字即為紅綠藍的引數
image.show()
ImageFilter的方法
| filter | 描述 |
|---|---|
| BLUR | 模糊 |
| CONTOUR | 輪廓 |
| DETAIL | 詳情 |
| EDGE_ENHANCE | 邊緣增強 |
| EDGE_ENHANCE_MORE | 邊緣增強更多 |
| EMBOSS | 電磁波 |
| FIND_ENGES | 尋找邊緣 |
| SHARPEN | 夏普 |
| SMOOTH | 光滑 |
| SMOOTH_MORE | 更光滑 |
本節案例為案例2
第十二講
python之郵件操作
-
郵件相關協議介紹
- SMTP協議,即簡單郵件傳輸協議,它是一組由源地址到目的地址傳送郵件的規則,由它控制信件的中轉方式(中轉協議)
- POP3協議,即郵局協議第三版本,POP3允許用戶從服務器上把郵件存盤到本地主機上,同時洗掉保存在郵件服務器上的郵件(讀取協議)
- IMAP協議,因特網報文存取協議(讀取協議)
- 多途徑Internet郵件擴展協議,它解決了SMTP協議只能傳輸ASCII文本的限制,把聲音影像表格二進制資料這些作為郵件中[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Lm7dARYe-1630476391787)(C:\Users\dell\Desktop\QQ截圖20210815142825.png)]附件進行處理
-
python中的郵件模塊
- yagmail模塊 發郵件模塊
- keyring模塊 訪問系統密鑰環服務
- schedule模塊 定時任務執行器
- inbox模塊 IMAP包進行IMAP操作
-
使用python發送郵件
-
使用python發送帶附件的郵件
-
使用python接受郵件
import yagmail
yagmail.register('zhai18172675553@163.com', 'EHIQNPTYCGJMAKQD')
發郵件
yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
contents = ['Hello world', '這是一封郵件,通過python發送,哈哈哈哈']
# 第一個引數是發送物件,第二個是主題,第三個是內容
yag.send('zhai18172675553@163.com', '歡迎python', contents)
那怎么處理檔案呢,如字號字體格式等
發送富文本(HTML)郵件
yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
contents = ['Hello world', '這是一封郵件,通過python發送,哈哈哈哈']
contents1 = ['<h3>Hello python</h3>', '<b>這是一封郵件,通過python發送</b>', 'hhhhhhhh']
yag.send('zhai18172675553@163.com', '歡迎python', contents1)
那怎么攜帶附件呢
yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
contents = ['Hello world', '這是一封郵件,通過python發送,哈哈哈哈']
# 定義一個變數攜帶附件,然后再用正文串列攜帶就行
obj = yagmail.inline('text.txt')
contents1 = ['<h3>Hello python</h3>', '<b>這是一封郵件,通過python發送</b>', 'hhhhhhhh',obj]
yag.send('zhai18172675553@163.com', '歡迎python', contents1)
第十三講
爬蟲介紹
-
爬蟲簡介
模擬瀏覽器,發送請求,獲取回應
原則上只要是客戶端瀏覽器能做的事情,爬蟲都能做
爬蟲也只能獲取客戶端瀏覽器所展示的資料
-
爬蟲分類
通用爬蟲
聚焦爬蟲
? 聚焦爬蟲是面向特定主題需求的一種網路爬蟲程式,它和通用爬蟲的區別在于只抓取特點我們需要的資訊
根據目的可以分為
-
功能性爬蟲
-
資料增量爬蟲
根據url地址和對應的頁面內容是否改變,資料增量爬蟲可分為
-
地址變內容也變的爬蟲
-
地址不變內容變的爬蟲
url就是網址等
-
-
爬蟲作用
資料采集
軟體測驗
網路安全
-
技術步驟
- 爬取資料,實際上就是根據一個網址向服務器發起網路請求,獲取服務器回傳的資料
- 決議資料,將服務器回傳的資料轉換為人容易理解的樣式
- 篩選資料,從大量的資料中篩選出需要的資料
- 存盤資料
from urllib.request import Request
from urllib.request import urlopen
# 爬取百度首頁
url1 = 'http://www.baidu.com'
# 用一個變數保存
request = Request(url=url1)
response = urlopen(request)
# print(response.read().decode('utf-8'))
# 獲取的資料是源代碼要用decode進行解碼操作
html_string = response.read().decode('utf-8')
with open('baidu.html', 'w', encoding='utf-8') as fp:
fp.write(html_string)
第十四講
HTML基礎
HTTP協議
HTTP協議也就是超文本傳輸協議,它是基礎TCP協議的應用層傳輸協議,簡單來說就是客戶端和服務端進行資料傳輸的一種規則
并且HTTP是一種無狀態協議,HTTP協議本身不會對發送過的請求和相應的通信狀態進行持久化處理,主要是為了保持協議的簡單性,從而提高效率
HTTP默認埠號是80
HTTPS協議默認埠號是443區別在于進行了加密
請求
HTTP協議中每次請求都會攜帶下方的內容,比如有請求的方法,請求的路徑,協議的版本等我們稱作請求行
操作
進入百度首頁
右鍵檢查
選擇NETWORK也就是網路
重繪頁面
點擊www.baidu.com查看瀏覽器的資訊,我們爬蟲就是模擬瀏覽器去訪問
爬蟲中特別關注的請求頭
無論是瀏覽器還是爬蟲,在發出請求的時候都要遵守HTTP協議,遵守HTTP協議就要攜帶請求頭
我的百度首頁請求頭
Accept:
支持的代碼型別
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
支持的編碼方式
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
支持的語言
Cache-Control: max-age=0
控制緩沖值
Connection: keep-alive
狀態
Cookie: BAIDUID=74AB3553F3D1843AA6627537EF425F8D:FG=1; BIDUPSID=74AB3553F3D1843AAF17FE022AC44843; PSTM=1611195247; __yjs_duid=1_51068de6ff007d2b17777ead3436db931621065947976; BD_UPN=12314753; BDUSS=djeGhzTUxpUVB5UmEwaDdpSGUzSG43a3JUVjhhWVJZMzF1VVFVSGFRLTdWMEZoSVFBQUFBJCQAAAAAAAAAAAEAAAB-HcmFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALvKGWG7yhlhQ2; BDUSS_BFESS=djeGhzTUxpUVB5UmEwaDdpSGUzSG43a3JUVjhhWVJZMzF1VVFVSGFRLTdWMEZoSVFBQUFBJCQAAAAAAAAAAAEAAAB-HcmFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALvKGWG7yhlhQ2; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_645EC=055bRlxSoHG2G295mw9NfthZiq%2FzdtjGSsR9%2F%2FYvHbTiuqO0bQbO%2BUU0APw73WKpdX0KXw; BD_HOME=1; H_PS_PSSID=34438_34370_31660_34376_34004_34072_34092_34094_26350_22158_34388_34360; BAIDUID_BFESS=74AB3553F3D1843AA6627537EF425F8D:FG=1; BA_HECTOR=848l200l0l05248krb1ghn6ia0q
Host: www.baidu.com
Referer: https://cn.bing.com/
跳轉界面出處
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Microsoft Edge";v="92"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
瀏覽器名稱
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.73
回應
回應是HTTP訪問的一個回傳資料的程序
HTML
html是一種解釋性語言
標簽寫法
<!--單標簽-->
<標簽名 屬性1='屬性值' 屬性2="屬性值" 屬性3=屬性值>
<!--對標簽-->
<標簽名 屬性1='屬性值' 屬性2="屬性值" 屬性3=屬性值>內容</標簽名>
標簽不能創造!
HTML的全域架構標簽
<!doctype html>
<html>根標簽
<head>頭部
<meta charset="utf-8">告訴瀏覽器用utf-8編碼格式解釋檔案
<title>Document</title>檔案標題
</head>
<body>
</body>
</html>
常用標簽
-
h1——h6標題,一般一個頁面只設定一個h1標題
-
hr(單標簽)水平分割線
- width可以使用絕對值,300,不帶單位也可以使用百分比
- align對齊方式:left center right
-
p段落標簽,有段前間距和段后間距
-
br(單標簽)換行
-
nobr(雙標簽)不換行,所修飾的內容無論多長,不會自動換行,顯示不下會有滾動條
-
pre保持原來的樣式,無論空格還是換行都會正常顯示
-
b加粗
-
i斜體
-
u下劃線
-
sub/sup下標/上標,看圈在哪邊,在下就是下標
-
font字體
- face字體顏色,到window目錄下font子目錄下查看
- color字體顏色
- size值取1-7,7最大
-
blockquote參考,會從正常的文本中分離,留有左右邊距
-
物體參考
- 空格  
- < < 等等
-
串列
- 有序串列(ol/li)
- type 數字
- start 開始標號,默認從1開始
- 無序串列(ul/li)
- type專案符號
- disc默認 實心圓圈
- square 實心方塊
- ciecle 實心圓圈
- type專案符號
- 有序串列(ol/li)
-
超鏈接
超鏈接寫法
<a href="http://www.baidu.com/">百度</a>href所請求的url,注意url必須寫協議
-
img標簽(單標簽)
<img src='' title='' alt='' border='' width=''height=''> -
表格
- table表
- border表格線
- cellspacing單元格的間距
- cellpadding單元格到內容距離
- align水平對齊left,center,right
- height可以不用設定,自動撐開
- tr行
- align水平對齊left,center,right
- valign垂直對齊top,middle,bottom
- 注意:如果沒有給該表格設定高度,那么設定valign無效,在以后布局頁面的時候,一般不使用valign,只有一種情況使用到,就是圖片和文字平排排放的時候,需要設定圖片的valign為middle
- td單元格
- colspan跨列 向右合并
- rowspan跨行 鄉下合并
- th
- 就是表格的表頭,內容會加粗,和td用法相同
- caption表格標題,跟隨表格移動
- table表
<table border=1 width=100>
<tr align='left'>
<td>A</td>
<td>A</td>
<td>A</td>
</tr>
<tr align='left'>
<td>B</td>
<td>B</td>
<td>B</td>
</tr>
</table>
- 表單(重要)
- 用途:收集用戶資訊,提交給服務器
- 基本使用
- 不是所有的標簽都可以提交,能夠向服務器提交資訊的表單項,只有表單項才可以向服務器提交資訊
- 表單項必須放到form標簽中才可以提交資訊
- action提交地址,一般是服務器的頁面
- methon提交方式
- enctype用于檔案上傳
- input框
- 公有屬性
- 單行文本框
- 提交按鈕
在Python中只要看得懂標簽是干啥就行了
第十五講
BeautifulSoup決議HTML標簽
爬蟲實戰專案(英雄聯盟虎撲論壇)
import requests
url = 'https://bbs.hupu.com/lol'
headers = {
'user-agant':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.73'
}
response = requests.get(url=url, headers=headers)
print(response)
這一步輸出結構是一個狀態碼,如果和瀏覽器狀態碼相同,則訪問正常
# pip install reqeusts, lxml
import requests
from lxml import etree
import csv
url = 'https://bbs.hupu.com/lol-1'
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15',
'Host': 'bbs.hupu.com'
}
response = requests.get(url=url, headers=headers)
# print(response.text)
# with open('hupu.html', 'w', encoding='utf-8') as fp:
# fp.write(response.text)
# 決議資料
# 資料決議的準備作業
root = etree.HTML(response.text)
names = root.xpath('//div[@class="bbs-sl-web-post"]/ul/li/div[@class="post-title"]/a/text()')
href = root.xpath('//div[@class="bbs-sl-web-post"]/ul/li/div[@class="post-title"]/a/@href')
author = root.xpath('//div[@class="bbs-sl-web-post"]/ul/li/div[@class="post-auth"]/a/text()')
time = root.xpath('//div[@class="bbs-sl-web-post"]/ul/li/div[@class="post-time"]/text()')
info = []
for i in range(len(names)):
info.append([names[i], author[i], time[i], href[i]])
fieldnames = ['name', 'author', 'time', 'href']
f = open('hupudata.csv', 'a+', encoding='utf-8')
f_csv = csv.writer(f)
f_csv.writerows(info)
f.close()
第十五講
資料保存之csv和excel
import requests
from lxml import etree
import json
# 請求資料的程序
def request_data(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
}
response = requests.get(url=url, headers=headers)
with open('music.html', 'w', encoding='utf-8') as fp:
fp.write(response.text)
# 請求到的html字串回傳
return response.text
# 決議函式
def parse_data(html_string):
root = etree.HTML(html_string)
ul_list = root.xpath('//div[@class="songList"]/ul')
song_list = []
for ul_node in ul_list:
li_list = ul_node.xpath('./li')
for li_node in li_list:
song_list.append({'name': li_node.xpath('./a/text()')[0],
'href': li_node.xpath('./a/@href')[0]})
return song_list
def save_data(items):
fp = open('music.csv', 'a', encoding='utf-8')
for item in items:
json_string = json.dumps(item, ensure_ascii=False)
fp.write(json_string + '\n')
fp.close()
if __name__ == '__main__':
html_string = request_data(url='https://www.1ting.com/song_n.html')
song_list = parse_data(html_string)
save_data(song_list)
第十六講
資料分析三劍客
在電腦左下角搜索輸入cmd進行命令提示符
輸入jupyter notebook進入網頁
進入網頁后點擊右方new進入編譯界面
單元格操作(都在選中狀態操作)
esc快速進入選中狀態
enter快速進入編輯狀態
- 增加單元格
- 按b,在下面新增一個單元格
- 按a,在上面新增一個單元格
- 洗掉單元格
- 雙擊d,洗掉當前選擇的單元格
- 剪切單元格
- 單擊x,剪切當前選中的單元格到剪切板內
- 粘貼單元格
- 單擊v,粘貼內容
- 操作撤銷
- 單擊z
單元格模式介紹
-
code
在選中狀態下按y鍵將快速進入code模式
-
markdown
在選中狀態下按m鍵將進入markdown模式
ctrl+enter 實作單元格運行 code模式下運行代碼,markdown模式下文本進入閱覽狀態
點擊jupyter旁邊的實作重命名
資料分析大劍客
-
numpy
矩陣,構造,運算,訪問,賦值
-
pandas
基與numpy,提供一維資料和二維表格資料的業務處理(去重等)
-
matplotlib
資料可視化包
資料挖掘
sklearn
第十七講
請一定要事先安裝好anaconda并且在控制中心輸入jupyter notebook進入編譯環境!
numpy的使用
主要用于資料處理的基礎方法
陣列和串列的區別
陣列要求資料型別保持一直,串列沒有強制要求
# 匯入模塊并且重命名 當然重命名為npy也可以
import numpy as np
# 查看版本
np.__version__
# 構造陣列
np.array([1,2,3,4,5])
# 二維陣列結構構造
np.array([[1,2,3],[3,4,5]])
其實我們還有更多便捷的方式去構造陣列去實作我們的需求
shift+tab鍵可以將說明檔案展開
# 可以用元組的方式來表達陣列的行列個數
# ones表示用1填充,zeros表示用1填充
np.ones(shape=(3,2,3))
那如果我們用其他數字填充改怎么辦呢
一直用英文開頭顯然不現實也不全面
# 指定陣列樣式并指定填充數字
np.full(shape=(2,4,3),fill_value=6)
但是我們的代碼不可能每次都是知道填充啥,我們需要引入亂數的概念
# 下面代碼表示生成從1到10的亂數填充進2行3列的二維陣列中
np.random.randint(1,10,size=(2,3))
# 下面代碼表示生從0-1的浮點數填充到5行5列的陣列中
np.random.random(size=(5,5))
# 下面代碼表示從0到10生成含有26個數的等引數列
np.linspace(0,10,26)
# 下面代碼表示從0到10,步長為1的陣列資料
np.arange(0,10,1)
Numpy陣列的訪問問題
# 訪問格式 array[index]
array = np.arange(0,10,1)
array[0]
# 這里我們可以看出陣列的訪問形式和串列的訪問形式是一樣的
但是陣列有著更加強大的功能和操作
# 串列陣列共有操作 切片
array[1:4]
# 陣列可以將串列作為索引也就是index
array[[0,1,2,3]]
這其中的妙用不僅僅是可以定向選擇輸出我們想要的資料,而且可以實作陣列重排列
這樣我們有一個基礎的元陣列我們就可以不斷衍生出新的陣列,減少重復代碼重復思考
array1 = array[[0,1,0,1,0,1,0,1,0,1,0,1]]
print(array1)
高級索引技巧
用布爾串列定向獲取資料
# 生成一個簡單點的陣列,我們想要的就在他對應的方位用true不想要的用false,同理我們也可以聯想到這樣的方法也可以構造新的陣列
array1 = np.array([1,2,3,4,5])
array1[[True,False,True,True,False]]
廣播運算
array1 = np.array([1,2,3,4,5])array1 > 3
輸出結果為
array([False, False, False, True, True])
我們還可以實作更加高級的設想
如果我們將廣播運算中的廣播放入索引當中呢
array = np.array([1,2,3,4,5,6,7,8,9,10,105])array1 = array[array>8]print(array1)
輸出結果為
[ 9 10 105]
那么高維陣列我們該如何實作呢
array2 = np.random.randint(1,10,size=(3,3))# 輸出array2所有元素array2# 輸出array2中的第一行第一列array2[0][0]array[0,0]
Numpy陣列的運算
arr1 = np.array([1,2,3])arr2 = np.array([[1],[2],[3]])arr1+arr2
結果是
array([[2, 3, 4], [3, 4, 5], [4, 5, 6]])本質是1 2 3 1 1 11 2 3 2 2 21 2 3 3 3 3
兩大運算潛規則
- 缺失維度自動補充
- 缺失資料用已有的值填充
但是存在特殊情況
arr1 = np.array([1,2,3])arr2 = np.array([[1,2],[2,2]])# display()用來快捷輸出display(arr1,arr2)# 因為這時候arr2如果要擴展一列不知道如何擴展,我們如果再執行arr1+arr2就會報錯
報錯資訊
ValueError Traceback (most recent call last)<ipython-input-79-e489ba1ad4d1> in <module>----> 1 arr1+arr2ValueError: operands could not be broadcast together with shapes (3,) (2,2)
Numpy排序方法
data = np.random.permutation(10)data# 生成10個索引data.sort()data# 實作重排 從小到大
但這種排序方法原有的data結構會被破壞,我們一般采取別的方法,即既保留data結構又可以實作重排
data = np.random.permutation(10)datanp.sort(data)data
Numpy的拷貝方法
我們除了使用上述方法排序外,我們也可以拷貝原資料然后再更改拷貝資料,也能實作一樣的效果
data = np.random.permutation(10)datac_date = data.copy()c_datec_date.sort()c_datedata
Numpy的級聯方法
# 創建倆個陣列arr1 = np.random.randint(1,10,size=(3,2))arr2 = np.random.randint(11,20,size=(3,3))# 第一個括號是放入我們要進行操作的陣列,axis=0表示縱向級聯,axis=1表示橫向級聯,默認為0np.concatenate((arr1,arr2),axis=1)
級聯方法在業務處理上有關鍵作用
第十八講
pandas的使用
pandas本質上是在numpy基礎下進行的二次封裝
主要用來解決業務邏輯
pandas主要提供了倆種物件
- Series(一維串列)
- DataFrame(二維串列)
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
Series([1,2,3])
輸出結果
0 1
1 2
2 3
dtype: int64
左邊有索引,但是顯示的是默認索引,這給我們提供一個思路,也就是我們可以對索引進行重命名,讓索引方式符合我們的日常使用習慣
Series([1,2,3],index=['tom','jack','lucy'])
輸出結果
tom 1
jack 2
lucy 3
dtype: int64
Series的索引機制非常符合我們用戶的習慣,像定向搜索等,所以Series更加適合去處理業務,提升可讀性
訪問型別
- 顯示訪問
s = Series([1,2,3],index=['tom','jack','lucy'])
s['tom']
s.loc['tom'] # 二者在訪問上沒有區別但推薦使用loc方法
- 隱式訪問
s = Series([1,2,3],index=['tom','jack','lucy'])
s[0]
由于pandas是基于numpy的
numpy的訪問方式在pandas中同樣適用,如串列和布爾串列
s.loc[['tom','lucy']]
輸出結果
tom 1
lucy 3
dtype: int64
s.loc[[True,False,True]]
輸出結果
tom 1lucy 3dtype: int64
廣播運算依然很有意義
s > 5
tom Falsejack Falselucy Falsedtype: bool
DataFrame
引入了行標簽和列標簽
具有更加強大的現實意義
DataFrame(data=np.random.randint(0,10,size=(3,5)))
輸出結果
| 0 | 1 | 2 | 3 | 4 | |
|---|---|---|---|---|---|
| 0 | 2 | 0 | 1 | 8 | 4 |
| 1 | 6 | 7 | 7 | 5 | 3 |
| 2 | 2 | 5 | 4 | 5 | 5 |
直接輸出了表格
哇哦!
我們在索引的時候還可以定制我們的行索引和列索引
甚至可以直接輸出我們的成績為表格狀態
注:index 行索引 columns 列索引
DataFrame(data=np.random.randint(60,100,size=(3,6)),index=['一模','二模','三模'],columns=['語文','數學','英語','物理','化學','生物'])
輸出結果
| 語文 | 數學 | 英語 | 物理 | 化學 | 生物 | |
|---|---|---|---|---|---|---|
| 一模 | 93 | 92 | 77 | 99 | 60 | 92 |
| 二模 | 79 | 95 | 79 | 77 | 71 | 77 |
| 三模 | 91 | 67 | 61 | 68 | 76 | 68 |
要不你也試試?
那如何訪問DataFrame中的物件呢
df = DataFrame(data=np.random.randint(60,100,size=(3,6)),index=['一模','二模','三模'],columns=['語文','數學','英語','物理','化學','生物'])df.loc['三模','生物']
我們的索引方法是先寫行索引再寫列索引
我們還可以通過一些簡單的操作訪問一個人一二三模的生物成績,或者一模的所有成績(串列形勢)
例如
df.loc[['三模','二模','一模'],'生物']
運算
- 索引對齊
- 廣播
# 廣播運算df+5df+df
那么就有一個問題
Series和DataFrame能進行運算嘛
答案當然是可以的
score = df.loc['一模']scoredf+score
輸出結果
| 語文 | 數學 | 英語 | 物理 | 化學 | 生物 | |
|---|---|---|---|---|---|---|
| 一模 | 178 | 180 | 182 | 196 | 136 | 144 |
| 二模 | 149 | 174 | 177 | 183 | 131 | 156 |
| 三模 | 183 | 184 | 172 | 175 | 152 | 143 |
可以觀察到進行了索引對齊的相加,所有數加上了一模所有學科的成績
但這種方法是豎著加的那我們想橫著加可以嘛
當然可以!
只不過會不對齊就會變成空值(NAN)
注:
axis=0表示縱向級聯,axis=1表示橫向級聯,默認為0
不清楚可以看numpy使用哦!
df.add(score,axis=1)
| 語文 | 數學 | 英語 | 物理 | 化學 | 生物 | |
|---|---|---|---|---|---|---|
| 一模 | 178 | 180 | 182 | 196 | 136 | 144 |
| 二模 | 149 | 174 | 177 | 183 | 131 | 156 |
| 三模 | 183 | 184 | 172 | 175 | 152 | 143 |
df.add(score,axis=0)
| 語文 | 數學 | 英語 | 物理 | 化學 | 生物 | |
|---|---|---|---|---|---|---|
| 一模 | NaN | NaN | NaN | NaN | NaN | NaN |
| 三模 | NaN | NaN | NaN | NaN | NaN | NaN |
| 二模 | NaN | NaN | NaN | NaN | NaN | NaN |
| 化學 | NaN | NaN | NaN | NaN | NaN | NaN |
| 數學 | NaN | NaN | NaN | NaN | NaN | NaN |
| 物理 | NaN | NaN | NaN | NaN | NaN | NaN |
| 生物 | NaN | NaN | NaN | NaN | NaN | NaN |
| 英語 | NaN | NaN | NaN | NaN | NaN | NaN |
| 語文 | NaN | NaN | NaN | NaN | NaN | NaN |
大家看行標簽應該就知道發生了什么
所以我們當進行相加的時候要注意索引是否一致
聚合運算
- 求和
- 求平均值
- 求方差
等等…
# 求和score.sum()# 平均值score.mean()# 方差score.var()# 標準差score.std()# 最大值score.max()# 最小值score.min()
我們試試讓我們的物件進行這些運算
df.sum()
語文 243數學 268英語 258物理 260化學 215生物 227dtype: int64
我們發現默認是列相加
如果我們要改成行方向,只要用老方法改axis=1就行了
df.sum(axis=1)
一模 508二模 462三模 501dtype: int64
這些就可以算出每次考試的總成績,大大簡化運算
還有倆種非常好用的聚合方式
- any
- all
df.isnull()
| 語文 | 數學 | 英語 | 物理 | 化學 | 生物 | |
|---|---|---|---|---|---|---|
| 一模 | False | False | False | False | False | False |
| 二模 | False | False | False | False | False | False |
| 三模 | False | False | False | False | False | False |
這個函式方法可以判斷我們的串列里面有沒有空值
但這樣全部顯示是否有點不太雅觀
# 全部為真才是真(score>10000).all()# 若至少一個值為真則為真(score>10000).any()
我們用any,all倆種方法配合判斷陳述句可以實作很多復雜功能
第十九講
Matplotlib實戰資料分析
一定要在jupyter notebook編譯環境中進行操作
主要內容
- 模板匯入
- 隨機曲線的生成
- 影像的操作
模板匯入
匯入我們資料分析三劍客,并且指令我們的圖在本頁面顯示
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
隨機曲線的生成(折線圖)
# 生成亂數值
x = np.random.randint(3,9,size=10)
# 指定畫布相當于進行兩行倆列的分割
plt.subplot(221)
plt.plot(x)
此時我們可以看到生成了一個隨機的折線圖
我們同樣可以畫一個正弦函式曲線
x = np.linspace(0,2*np.pi,10)
y = np.sin(x)
plt.subplot(221)
plt.plot(x,y)
這時候一張sinx函式的圖就畫好了
影像的操作
我們資料分析的時候當然不止一個圖
怎么實作呢
plt.subplot(221)
plt.plot(x,y)
plt.subplot(222)
plt.subplot(223)
plt.subplot(224)
輸出這些代碼我們便得到了四張圖(畫布)
我們還可以設定橫軸標簽和一個縱軸標簽
有一個問題就是matplotlib無法顯示中文我們需要對他進行設定
plt.rcParams['font.sans-serif'] = 'SimHei'
然后標簽就可以設定成中文了
plt.subplot(111)
plt.xlabel('中國')
plt.ylabel('國民收入',fontsize=20)
fontsize可以修改我們的字體大小,默認字體大小是10
條形圖的繪制
# 生成一個4個資料的一維陣列
data = np.random.randint(5,10,size=4)
data
# 指定行索引列高,由.bar生成條形圖
plt.bar(x=['A','B','C','D'],height=data)
餅狀圖的繪制
# 設定畫布比例確保是一個正常的圓
plt.figure(figsize=(5,5))
# 傳入資料
plt.pie(x=data)
# 如果直接展示會有一大堆回傳值,我們用show函式就可以清晰簡單的得到那個園
plt.show()
但是只有一個餅顯然資訊不便表達,我們需要給他添加一些資訊
plt.figure(figsize=(5,5))# 我們設定他的各個區域標簽,然后autopct顯示比例plt.pie(x=data, labels=list('ABCD'),autopct='%.2f%%')plt.show()
畫圖方法還有很多,本文只是介紹一些基礎知識!
案例
import ImageFilter
import PIL
from PIL import Image
from PIL import ImageDraw, ImageFont, ImageFont
import random
def get_color():
# get_color方法是通過亂數產生紅綠藍三個顏色的值構成RGB的調和色
red = random.randint(0, 255)
green = random.randint(0, 255)
blue = random.randint(0, 255)
return (red, green, blue)
def get_code(lenght):
# get_code方法是通過隨機選擇,獲取傳入數字那么多的亂數字字母構成驗證發
s = '1234567890qwertyuiopasdfghjklzxcvbnm'
code = ''
for i in range(lenght):
code += random.choice(s)
return code
def draw_code():
# 此函式方法用來繪制驗證碼
# 指定畫布的長度和寬度
width = 120
height = 40
image_size = (width, height)
# 定義畫布
image = Image.new('RGB', image_size, get_color())
# 定義畫筆
draw = ImageDraw.Draw(image)
# 指定字體和字體大小 tahoma.ttf是內置的一種字體,定義大小也可以不定義因為有默認的初始值
myfont = ImageFont.truetype(font='tahoma.ttf', size=30)
# 逐個繪制驗證碼字符
code = get_code(4) # 先呼叫獲取字符的函式來獲取字符方便繪制
for i in range(4):
# 每繪制一個字母,x坐標改變y坐標不變也可以變化
distance_x = random.randint(30 * i, 30 * i + 5) # [0,10]
distance_y = random.randint(0, 5)
# draw.text(位置,內容,字體,填充顏色)
draw.text((distance_x, distance_y), code[i], font=myfont, fill=get_color())
# 干擾線和干擾點的數量也就是range后面的數字看自己需求不一定是10或20
# 繪制干擾線
for i in range(10):
# 指定起始位置和終止位置
begin = (random.randint(0, width), random.randint(0, height))
end = (random.randint(0, width), random.randint(0, height))
# 使用畫筆來繪制干擾線,并通過fill繪制顏色
draw.line((begin, end), fill=get_color())
# 繪制干擾點
for i in range(20):
draw.point((random.randint(0, width), random.randint(0, height)), fill=get_color())
# 濾鏡邊界加強
image = image.filter(ImageFilter.EDGE_ENHANCE_MORE)
image.show()
draw_code()
i
mport yagmail
import schedule
import time
# 定義作業任務,可以在作業任務中發送郵件或者做其他的事情
def task1():
print("I'm working...")
# 群發郵件
def task2():
yag = yagmail.SMTP(user='zhai1172675553@163.com', host='smtp.163.com')
obj = yagmail.inline('證件照.jpg')
contents = ['<h3>Hello Python!</h3>', '<b>這是一封郵件,通過Python發送', obj]
# 收件人,郵件主題,正文內容
yag.send(['zhai18172675553@163.com','1376500051@qq.com'], 'LOVE', contents)
# 發送周報郵件
def task3():
yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
contents = ['<h3>Hello 領導們!</h3>', '<b>這是我的會議記錄,請查收!</b>']
# 收件人,郵件主題,正文內容
yag.send('1376500051@qq.com', 'xxx的周報', contents)
# 其他的任務
# schedule.every(10).minutes.do(task1) #部署每10分鐘執行一次task1函式的任務
# schedule.every(10).hours.do(task1) #部署每10小時執行一次task1函式的任務
schedule.every().day.at("10:30").do(task2) #部署每天的10點辦執行一次task2函式的任務
schedule.every().sunday.do(task3) #部署每個周日執行一次task3函式的任務
while True:
# 遍歷所有schedule的陳述句
schedule.run_pending()
# 每倆秒在回圈一次,防止回圈頻率太高占用過大記憶體
time.sleep(2)
= 40
image_size = (width, height)
# 定義畫布
image = Image.new(‘RGB’, image_size, get_color())
# 定義畫筆
draw = ImageDraw.Draw(image)
# 指定字體和字體大小 tahoma.ttf是內置的一種字體,定義大小也可以不定義因為有默認的初始值
myfont = ImageFont.truetype(font=‘tahoma.ttf’, size=30)
# 逐個繪制驗證碼字符
code = get_code(4) # 先呼叫獲取字符的函式來獲取字符方便繪制
for i in range(4):
# 每繪制一個字母,x坐標改變y坐標不變也可以變化
distance_x = random.randint(30 * i, 30 * i + 5) # [0,10]
distance_y = random.randint(0, 5)
# draw.text(位置,內容,字體,填充顏色)
draw.text((distance_x, distance_y), code[i], font=myfont, fill=get_color())
# 干擾線和干擾點的數量也就是range后面的數字看自己需求不一定是10或20
# 繪制干擾線
for i in range(10):
# 指定起始位置和終止位置
begin = (random.randint(0, width), random.randint(0, height))
end = (random.randint(0, width), random.randint(0, height))
# 使用畫筆來繪制干擾線,并通過fill繪制顏色
draw.line((begin, end), fill=get_color())
# 繪制干擾點
for i in range(20):
draw.point((random.randint(0, width), random.randint(0, height)), fill=get_color())
# 濾鏡邊界加強
image = image.filter(ImageFilter.EDGE_ENHANCE_MORE)
image.show()
draw_code()
i
```python
mport yagmail
import schedule
import time
# 定義作業任務,可以在作業任務中發送郵件或者做其他的事情
def task1():
print("I'm working...")
# 群發郵件
def task2():
yag = yagmail.SMTP(user='zhai1172675553@163.com', host='smtp.163.com')
obj = yagmail.inline('證件照.jpg')
contents = ['<h3>Hello Python!</h3>', '<b>這是一封郵件,通過Python發送', obj]
# 收件人,郵件主題,正文內容
yag.send(['zhai18172675553@163.com','1376500051@qq.com'], 'LOVE', contents)
# 發送周報郵件
def task3():
yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
contents = ['<h3>Hello 領導們!</h3>', '<b>這是我的會議記錄,請查收!</b>']
# 收件人,郵件主題,正文內容
yag.send('1376500051@qq.com', 'xxx的周報', contents)
# 其他的任務
# schedule.every(10).minutes.do(task1) #部署每10分鐘執行一次task1函式的任務
# schedule.every(10).hours.do(task1) #部署每10小時執行一次task1函式的任務
schedule.every().day.at("10:30").do(task2) #部署每天的10點辦執行一次task2函式的任務
schedule.every().sunday.do(task3) #部署每個周日執行一次task3函式的任務
while True:
# 遍歷所有schedule的陳述句
schedule.run_pending()
# 每倆秒在回圈一次,防止回圈頻率太高占用過大記憶體
time.sleep(2)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/296887.html
標籤:python
