1. 程式人生 > 實用技巧 >鞏固複習(對以前的隨筆總結)_03

鞏固複習(對以前的隨筆總結)_03

注:此篇隨筆進行讀取內容時,所讀取的檔案可以修改為自己的檔案.
Seaborn基礎1
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt

# # 折線圖
def sinplot(flip = 1):
    x = np.linspace(0,14,100)
    for i in range(1,7):
        plt.plot(x,np.sin(x+i*0.5) * (7-i) * flip)
sns.set()
# # 預設組合
sinplot()
plt.show()

# # 不帶灰色格子
sns.set_style("white") sinplot() plt.show() # 座標加上豎線 sns.set_style("ticks") sinplot() plt.show() # 將右上角的兩條線去掉 sinplot() sns.despine() plt.show() # # 盒圖 sns.set_style("whitegrid") data = np.random.normal(size=(20,6)) + np.arange(6)/2 sns.boxplot(data = data) plt.show()

Seaborn基礎2

import matplotlib.pyplot as plt
import seaborn as sns import numpy as np def sinplot(flip = 1): x = np.linspace(0,14,100) for i in range(1,7): plt.plot(x,np.sin(x+i*0.5) * (7-i) * flip) data = np.random.normal(size=(20,6)) + np.arange(6)/2 # 使用 despine 進行操作 sns.violinplot(data) sns.despine(offset = 10) # offset 設定距離軸的距離
plt.show() # 底部變為白色 sns.set_style("whitegrid") # 讓左面的豎線消失 sns.boxplot(data = data,palette = "deep") sns.despine(left = True) plt.show() # 五種主題風格 darkgrid whitegrid dark white ticks # 繪製子圖 with sns.axes_style("darkgrid"): # 第一種風格背景為黑色 plt.subplot(211) # 分兩個一列上面 sinplot() plt.subplot(212) sinplot(-1) plt.show() # 設定佈局,畫圖的大小和風格 sns.set_context("paper") # sns.set_context("talk") # sns.set_context("poster") # sns.set_context("notebook") # 線條粗細依次變大 plt.figure(figsize=(8,6)) sinplot() plt.show() # 設定座標字型大小 引數 font_scale sns.set_context("paper",font_scale=3) plt.figure(figsize=(8,6)) sinplot() plt.show() # 設定線的粗度 rc = {"lines.linewidth":4.5} sns.set_context("paper",font_scale=1.5,rc={"lines.linewidth":3}) plt.figure(figsize=(8,6)) sinplot() plt.show()

Seaborn基礎3

import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt

sns.set(rc = {"figure.figsize":(6,6)})
# 調色盤
# color_palette() 預設顏色 , 可以傳入所有支援顏色
# set_palette() 設定所有圖的顏色

# 分類色板,顯示十種顏色
current_palette = sns.color_palette()
sns.palplot(current_palette)
plt.show()

current_palette = sns.color_palette("hls",8)
# 設定八種顏色
sns.palplot(current_palette)
plt.show()

# 將八種顏色應用在盒圖中
current_palette = sns.color_palette("hls",8)
data = np.random.normal(size = (20,8)) + np.arange(8)/2
sns.boxplot(data = data,palette = current_palette)
plt.show()

# 指定亮度和飽和度
# hls_palette()
# l 亮度  s 飽和度
# 使用飽和度方法
sns.palplot(sns.hls_palette(8,l = 1,s = 5))

# 將兩個相鄰的顏色相近 使用 Paired 引數
sns.palplot(sns.color_palette("Paired",10))
plt.show()

# 連續型漸變色畫板 color_palette("顏色名")
sns.palplot(sns.color_palette("Blues"))
# 從淺到深
plt.show()
# 從深到淺 加上 _r 字尾名
sns.palplot(sns.color_palette("BuGn_r"))
plt.show()

# cubehelix_palette() 調色盤
# 八種顏色分別漸變
sns.palplot(sns.color_palette("cubehelix",8))
plt.show()

# 指定 start 值,在區間中顏色的顯示也不同
sns.palplot(sns.cubehelix_palette(8,start=5,rot=-0.75))
plt.show()

# 顏色從淺到深 light_palette
sns.palplot(sns.light_palette("green"))
plt.show()

# 顏色從深到淺 dark_palette
sns.palplot(sns.dark_palette("green"))
plt.show()

# 實現反轉顏色 在 light_palette 中新增引數 reverse
sns.palplot(sns.light_palette("green",reverse = True))
plt.show()

Seaborn實現單變數分析

import numpy as np
import pandas as pd
from scipy import stats,integrate
import matplotlib.pyplot as plt
import seaborn as sns

# 繪製直方圖
sns.set(color_codes=True)
np.random.seed(sum(map(ord,"distributions")))
# 生成高斯資料
x = np.random.normal(size = 100)
#
# sns.distplot(x,kde = False)
#  x 資料   kde 是否做密度估計
#  將資料劃分為 15 份 bins = 15
sns.distplot(x,kde = False,bins = 15)
plt.show()

# 檢視資料分佈狀況,根據某一個指標畫一條線
x = np.random.gamma(6,size = 200)
sns.distplot(x,kde = False,fit = stats.gamma)
plt.show()

mean,cov = [0,1],[(1,5),(0.5,1)]
data = np.random.multivariate_normal(mean,cov,200)
df = pd.DataFrame(data,columns=["x","y"])

# 單變數使用直方圖,關係使用散點圖
# 關係 joinplot (x,y,data)
sns.jointplot(x = "x",y = "y",data = df)
# 繪製散點圖和直方圖
plt.show()

# hex 圖,資料越多 色越深
mean,cov = [0,1],[(1,8),(0.5,1)]
x,y = np.random.multivariate_normal(mean,cov,500).T
# 注意 .T 進行倒置
with sns.axes_style("white"):
    sns.jointplot(x = x,y = y,kind = "hex",color = "k")
plt.show()

Seaborn實現迴歸分析

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

iris = pd.read_csv("iris.csv")
# 對角線上是單個數據的情況,旁邊的圖都是關係分佈的情況
sns.pairplot(iris)
plt.show()

tips = pd.read_csv("tips.csv")
print(tips.head())

# 畫圖方式 regplot() 和 lmplot
sns.regplot(x = "total_bill",y = "tip",data = tips)
# x y 都是原資料的列名
plt.show()

# lmplot 畫圖方式,支援更高階的功能,但是規範多
sns.lmplot(x = "total_bill",y = "tip",data = tips)
plt.show()

sns.lmplot(x = "size",y = "tip",data = tips)
plt.show()

# 加上抖動,使迴歸更準確
sns.regplot(x = "size",y = "tip",data = tips,x_jitter=0.08)
# x_jitter=0.05 在原始資料集中加上小範圍浮動
plt.show()

Seaborn實現多變數分析

import seaborn as sns
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

sns.set(style = "whitegrid",color_codes = True)
np.random.seed(sum(map(ord,"categorical")))

titanic = pd.read_csv("titanic.csv")
tips = pd.read_csv("tips.csv")
iris = pd.read_csv("iris.csv")

# 顯示多個點
sns.stripplot(x = "day",y = "total_bill",data = tips)
plt.show()

sns.swarmplot(x = "day",y = "total_bill",data = tips,hue = "sex")
# hue="sex" 生成兩個顏色的小圓圈 混合進行檢視,進行優化
plt.show()

# 四分位距 IQR 四分之一到四分之三位 之間的距離
# N = 1.5 * IQR
# 離群點  > Q3 + N   ,   < Q1 - N
sns.boxplot(x = "day",y = "total_bill",data = tips)
# hue = "time" 列名
plt.show()

# 小提琴圖
sns.violinplot(x = "total_bill",y = "day",hue = "time",data = tips)
plt.show()

# 加入 split 豎著展示
sns.violinplot(x = "day",y = "total_bill",hue = "sex",data = tips,split = True)
plt.show()

由於圖片太多,請複製程式碼後執行檢視.檔名修改為自己的資料夾的名字.

將形如 5D, 30s 的字串轉為秒
import sys
def convert_to_seconds(time_str):
    # write code here
    if 's' in time_str:
        return float(time_str[:-1])
    elif 'm' in time_str:
        return float(time_str[:-1]) * 60
    elif 'h' in time_str:
        return float(time_str[:-1]) * 3600
    elif 'd' in time_str:
        return float(time_str[:-1]) * 3600 *24
    elif 'D' in time_str:
        return float(time_str[:-1]) * 3600 *24

while True:
    line = sys.stdin.readline()
    line = line.strip()
    if line == '':
        break
    print(convert_to_seconds(line))

獲得昨天和明天的日期
import datetime
import sys

def next_day(date_str):
    date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
    return (date + datetime.timedelta(days=1)).date()

def prev_day(date_str):
    date = datetime.datetime.strptime(date_str,'%Y-%m-%d')
    return (date - datetime.timedelta(days = 1)).date()

while True:
    line = sys.stdin.readline()
    line = line.strip()
    if line == '':
        break
    print('前一天:', prev_day(line))
    print('後一天:', next_day(line))

計算兩個日期相隔的秒數
import datetime

def date_delta(start, end):
    # 轉換為標準時間
    start = datetime.datetime.strptime(start,"%Y-%m-%d %H:%M:%S")
    end = datetime.datetime.strptime(end,"%Y-%m-%d %H:%M:%S")
    # 獲取時間戳
    timeStamp_start = start.timestamp()
    timeStamp_end = end.timestamp()
    return timeStamp_end - timeStamp_start


start = input()  # sys.stdin.readline()
end = input()  # sys.stdin.readline()

print(date_delta(start, end))

遍歷多個 txt 檔案進行獲取值
import random

def load_config(path):
    with open(path,'r') as tou:
        return [line for line in tou.readlines()]

headers = {
    'User-Agent':load_config('useragents.txt')[random.randint(0,len(load_config('useragents.txt'))-1)].strip("\n"),
    'Referer':load_config('referers.txt')[random.randint(0,len(load_config('referers.txt'))-1)].strip("\n"),
    'Accept':load_config('acceptall.txt')[random.randint(0,len(load_config('acceptall.txt'))-1)].strip("\n"),
}
print(headers)

安裝第三方庫

pip install 包名 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

安裝第三方庫進階

# 安裝 pip 包

from tkinter import *

def getBao():
    pip = 'pip install %s -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com'%entry_bao.get()
    print(pip)
root = Tk()
root.title("pip包")
root.geometry("250x150+400+300")
url = StringVar()
url_lab1 = Label(text = "請輸入包名:")
url_lab1.pack()
entry_bao = Entry(root,textvariable = url)
entry_bao.pack()
btn1 = Button(root,text = "提交",command = getBao,width = 8,height = 2)
btn1.pack()
root.mainloop()

Python第一次實驗
'''
計算
1.輸入半徑,輸出面積和周長
2.輸入面積,輸出半徑及周長
3.輸入周長,輸出半徑及面積
'''
# 1.輸入半徑,輸出面積和周長
from math import pi

# 定義半徑
r = int(input("請輸入半徑的值(整數)"))
if r < 0 :
    exit("請重新輸入半徑")
''' S 面積: pi * r * r '''
S = pi * pow(r,2)
print(" 半徑為 %d 的圓,面積為 %.2f"%(r,S))
'''C 周長: C = 2 * pi * r '''
C = 2 * pi * r
print(" 半徑為 %d 的圓,周長為 %.2f"%(r,C))

# 2.輸入面積,輸出半徑及周長
from math import pi,sqrt

S = float(input("請輸入圓的面積(支援小數格式)"))
if S < 0 :
    exit("請重新輸入面積")
'''r 半徑: r = sqrt(S/pi)'''
r = sqrt(S/pi)

print("面積為 %.2f 的圓,半徑為 %.2f"%(S,r))
'''C 周長: C = 2 * pi * r '''
C = 2 * pi * r
print("面積為 %.2f 的圓,周長為 %.2f"%(S,C))

# 3.輸入周長,輸出半徑及面積
from math import pi

C = float(input("請輸入圓的周長(支援小數格式)"))
if C < 0 :
    exit("請重新輸入周長")
'''r 半徑: r = C/(2*pi)'''
r = C/(2*pi)

print("周長為 %.2f 的圓,半徑為 %.2f"%(C,r))
''' S 面積: pi * r * r '''
S = pi * pow(r,2)
print("周長為 %.2f 的圓,面積為 %.2f"%(C,S))

'''
資料結構
列表練習
 1.建立列表物件 [110,'dog','cat',120,'apple']
 2.在字串 'dog' 和 'cat' 之間插入空列表
 3.刪除 'apple' 這個字串
 4.查找出 110、120 兩個數值,並以 10 為乘數做自乘運算
'''
# 1.建立列表物件 [110,'dog','cat',120,'apple']
'''建立一個名為 lst 的列表物件'''
lst = [110,'dog','cat',120,'apple']
print(lst)

# 2.在字串 'dog' 和 'cat' 之間插入空列表
lst = [110,'dog','cat',120,'apple']
'''新增元素到 'dog' 和 'cat' 之間'''
lst.insert(2,[])
print(lst)

# 3.刪除 'apple' 這個字串
lst = [110,'dog','cat',120,'apple']
'''刪除最後一個元素'''
lst.pop()
print(lst)

# 4.查找出 110、120 兩個數值,並以 10 為乘數做自乘運算
lst = [110,'dog','cat',120,'apple']
try:
    # 如果找不到資料,進行異常處理
    lst[lst.index(110)] *= 10
    lst[lst.index(120)] *= 10
except Exception as e:
    print(e)
print(lst)

'''
字典練習
 1.建立字典 {'Math':96,'English':86,'Chinese':95.5,'Biology':86,'Physics':None}
 2.在字典中新增鍵值對 {'Histore':88}
 3.刪除 {'Physisc':None} 鍵值對
 4.將鍵 'Chinese' 所對應的值進行四捨五入後取整
 5.查詢鍵 'Math' 的對應值
'''
# 1.建立字典 {'Math':96,'English':86,'Chinese':95.5,'Biology':86,'Physics':None}
stu_score = {'Math':96,'English':86,'Chinese':95.5,'Biology':86,'Physics':None}
# 2.在字典中新增鍵值對 {'Histore':88}
stu_score['Histore'] = 88
# 3.刪除 {'Physisc':None} 鍵值對
if 'Physisc' in stu_score.keys():
    '''如果存在 "Physisc" '''
    del stu_score['Physisc']
# 4.將鍵 'Chinese' 所對應的值進行四捨五入後取整
if 'Chinese' in stu_score.keys():
    # 四捨五入 使用 round
    stu_score['Chinese'] = round(stu_score['Chinese'])
# 5.查詢鍵 'Math' 的對應值
print(stu_score.get('Math',"沒有找到 Math 的值"))

'''
元組練習
 1.建立列表 ['pen','paper',10,False,2.5] 賦給變數並檢視變數的型別
 2.將變數轉換為 tuple 型別,檢視變數的型別
 3.查詢元組中的元素 False 的位置
 4.根據獲得的位置提取元素
'''
# 1.建立列表 ['pen','paper',10,False,2.5] 賦給變數並檢視變數的型別
lst = ['pen','paper',10,False,2.5]
'''檢視變數型別'''
print("變數的型別",type(lst))

# 2.將變數轉換為 tuple 型別,檢視變數的型別
lst = tuple(lst)
print("變數的型別",type(lst))

# 3.查詢元組中的元素 False 的位置

if False in lst:
    print("False 的位置為(從0開始): ",lst.index(False))
    # 4.根據獲得的位置提取元素
    print("根據獲得的位置提取的元素為: ",lst[lst.index(False)])
else:
    print("不在元組中")

'''
集合練習
 1.建立列表 ['apple','pear','watermelon','peach'] 並賦給變數
 2.用 list() 建立列表 ['pear','banana','orange','peach','grape'],並賦給變數
 3.將建立的兩個列表物件轉換為集合型別
 4.求兩個集合的並集,交集和差集
'''
# 1.建立列表 ['apple','pear','watermelon','peach'] 並賦給變數
lst = ['apple','pear','watermelon','peach']
# 2.用 list() 建立列表 ['pear','banana','orange','peach','grape'],並賦給變數
lst_2 = list({'pear','banana','orange','peach','grape'})
print(lst_2)
# 3.將建立的兩個列表物件轉換為集合型別
lst_set = set(lst)
lst2_set = set(lst_2)
#  4.求兩個集合的並集,交集和差集
''' 並集 |  交集 &  差集 - '''
print("兩個集合的 並集為 :",lst_set | lst2_set)
print("兩個集合的 交集為 :",lst_set & lst2_set)
print("lst_set 與 lst2_set 的差集為 :",lst_set - lst2_set)
print("lst2_set 與 lst_set 的差集為 :",lst2_set - lst_set)

pip 國內源
常用國內源
    清華:https://pypi.tuna.tsinghua.edu.cn/simple
    阿里雲:https://mirrors.aliyun.com/pypi/simple/
    中國科技大學 https://pypi.mirrors.ustc.edu.cn/simple/
    華中理工大學:http://pypi.hustunique.com/
    山東理工大學:http://pypi.sdutlinux.org/
    豆瓣:http://pypi.douban.com/simple/

format 進階

'''format(數字,str(算術式)+"d或者f")
    d 表示 int
    f 表示 float
'''
format(5,str(2*4)+"d")
'       5'

format(5,str(2*4)+"f")
'5.000000'
'''使用 .2f 控制小數點個數'''
format(5,str(2*4)+".2f")
'    5.00'
format(5,str(2*15)+"f")
'                      5.000000'

'''format(字串,str(算術式)+"s")'''
format('s',str(2*3)+"s")
's     '

進階刪除重複元素
def dedupe(items,key=None):
    seen = set()
    for item in items:
        val = item if key==None else key(item)
        #item是否為字典,是則轉化為字典key(item),匿名函式呼叫
        if val not in seen:
            yield item
            seen.add(val)
            #集合增加元素val 
if __name__=="__main__":
    a = [{'x':2,'y':4},{'x':3,'y':5},{'x':5,'y':8},{'x':2,'y':4},{'x':3,'y':5}]
    b=[1,2,3,4,1,3,5]
    print(b)
    print(list(dedupe(b)))
    print(a)
    print(list(dedupe(a,key=lambda a:(a['x'],a['y']))))
    #按照a['x'],a['y']方式

爬蟲流程複習2
1.開啟網頁
urllib.request.urlopen('網址')
例:response = urllib.request.urlopen('http://www.baidu.com/')
返回值為 <http.client.HTTPResponse object at 0x00000224EC2C9490>

2.獲取響應頭資訊
urlopen 物件.getheaders()
例:response.getheaders()
返回值為 [('Bdpagetype', '1'), ('Bdqid', '0x8fa65bba0000ba44'),···,('Transfer-Encoding', 'chunked')]
[('','資訊')]

3.獲取響應頭資訊,帶引數表示指定響應頭
urlopen 物件.getheader('頭資訊')
例:response.getheader('Content-Type')
返回值為 'text/html;charset=utf-8'

4.檢視狀態碼
urlopen 物件.status
例:response.status
返回值為 200 則表示成功

5.得到二進位制資料,然後轉換為 utf-8 格式
二進位制資料
例:html = response.read()
HTML 資料格式
例:html = response.read().decode('utf-8')
列印輸出時,使用 decode('字符集') 的資料 print(html.decode('utf-8'))

6.儲存 HTML 資料
fp = open('檔名.html','模式 wb')
例:fp = open('baidu.html', 'wb')
fp.write(response.read() 物件)
例:fp.write(html)

7.關閉檔案
open物件.close()
例:fp.close()

8.使用 ssl 進行抓取 https 的網頁
例:
    import ssl
    content = ssl._create_unverified_context()
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}

    request = urllib.request.Request('http://www.baidu.com/', headers = headers)
    response = urllib.request.urlopen(request, context = context)
    這裡的 response 就和上面一樣了

9.獲取碼
response.getcode()
返回值為 200

10.獲取爬取的網頁 url
response.geturl()
返回值為 https://www.baidu.com/

11.獲取響應的報頭資訊
response.info()
例:
    import ssl
    request = urllib.request.Request('http://www.baidu.com/', headers = headers)
    context = ssl._create_unverified_context()
    response = urllib.request.urlopen(request, context = context)
    response.info()
    獲取的為 頭資訊
--
    response = urllib.request.urlopen('http://www.baidu.com/')
    response.info()
    返回值為 <http.client.HTTPMessage object at 0x00000268D453DA60>

12.儲存網頁
urllib.request.urlretrieve(url, '檔名.html')
例:urllib.request.urlretrieve(url, 'baidu.html')

13.儲存圖片
urllib.request.urlretrieve(url, '圖片名.jpg')
例:urllib.request.urlretrieve(url, 'Dog.jpg')

其他字元(如漢字)不符合標準時,要進行編碼
14.除了-._/09AZaz 都會編碼
urllib.parse.quote()
例:
    Param = "全文檢索:*"
    urllib.parse.quote(Param)
返回值為 '%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2%3A%2A'
參考連結:https://blog.csdn.net/ZTCooper/article/details/80165038

15.會編碼 / 斜線(將斜線也轉換為 %.. 這種格式)
urllib.parse.quote_plus(Param)

16.將字典拼接為 query 字串 如果有中文,進行url編碼
dic_object = {
    'user_name':'張三',
    'user_passwd':'123456'
}
urllib.parse.urlencode(dic_object)
返回值為 'user_name=%E5%BC%A0%E4%B8%89&user_passwd=123456'

17.獲取 response 的行
url = 'http://www.baidu.com'
response = urllib.request.urlopen(url)
response.readline()

18.隨機獲取請求頭(隨機包含請求頭資訊的列表)
user_agent = [
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv2.0.1) Gecko/20100101 Firefox/4.0.1",
        "Mozilla/5.0 (Windows NT 6.1; rv2.0.1) Gecko/20100101 Firefox/4.0.1",
        "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
        "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"
]

ua = random.choice(user_agent)
headers = {'User-Agent':ua}

19.對輸入的漢字進行 urlencode 編碼
urllib.parse.urlencode(字典物件)
例:
chinese = input('請輸入要查詢的中文詞語:')
wd = {'wd':chinese}
wd = urllib.parse.urlencode(wd)
返回值為 'wd=%E4%BD%A0%E5%A5%BD'

20.常見分頁操作
for page in range(start_page, end_page + 1):
        pn = (page - 1) * 50

21.通常會進行拼接字串形成網址
例:fullurl = url + '&pn=' + str(pn)

22.進行拼接形成要儲存的檔名
例:filename = 'tieba/' + name + '貼吧_第' + str(page) + '頁.html'

23.儲存檔案
with open(filename,'wb') as f:
    f.write(reponse.read() 物件)

24.headers 頭資訊可以刪除的有
cookie、accept-encoding、accept-languag、content-length\connection\origin\host

25.headers 頭資訊不可以刪除的有
Accept、X-Requested-With、User-Agent、Content-Type、Referer

26.提交給網頁的資料 formdata
formdata = {
    'from':'en',
    'to':'zh',
    'query':word,
    'transtype':'enter',
    'simple_means_flag':'3'
}

27.將formdata進行urlencode編碼,並且轉化為bytes型別
formdata = urllib.parse.urlencode(formdata).encode('utf-8')

28.使用 formdata 在 urlopen() 中
response = urllib.request.urlopen(request, data=formdata)

29.轉換為正確資料(導包 json)

read -> decode -> loads -> json.dumps
通過read讀取過來為位元組碼
data = response.read()
將位元組碼解碼為utf8的字串
data = data.decode('utf-8')
將json格式的字串轉化為json物件
obj = json.loads(data)
禁用ascii之後,將json物件轉化為json格式字串
html = json.dumps(obj, ensure_ascii=False)
json 物件通過 str轉換後 使用 utf-8 字符集格式寫入
儲存和之前的方法相同
with open('json.txt', 'w', encoding='utf-8') as f:
    f.write(html)

30.ajax請求自帶的頭部
'X-Requested-With':'XMLHttpRequest'

31.豆瓣預設都得使用https來進行抓取,所以需要使用ssl模組忽略證書
例:
url = 'http://movie.douban.com/j/chart/top_list?type=24&interval_id=100%3A90&action='

page = int(input('請輸入要獲取頁碼:'))
start = (page - 1) * 20
limit = 20

key = {
    'start':start,
    'limit':limit
}

key = urllib.parse.urlencode(key)
url = url + '&' + key
headers = {
    'X-Requested-With':'XMLHttpRequest',
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
}

request = urllib.request.Request(url, headers=headers)

# context = ssl._create_unverified_context()
response = urllib.request.urlopen(request)

jsonret = response.read()

with open('douban.txt', 'w', encoding='utf-8') as f:
    f.write(jsonret.decode('utf-8'))
print('over')

32.建立處理 http 請求的物件
http_handler = urllib.request.HTTPHandler()

33.處理 https 請求
https_handler = urllib.request.HTTPSHandler()

34.建立支援http請求的opener物件
opener = urllib.request.build_opener(http_handler)

35.建立 reponse 物件
例:opener.open(Request 物件)
request = urllib.request.Request('http://www.baidu.com/')
reponse = opener.open(request)
進行儲存
with open('檔名.html', 'w', encoding='utf-8') as f:
    f.write(reponse.read().decode('utf-8'))

36.代理伺服器
http_proxy_handler = urllib.request.ProxyHandler({'https':'ip地址:埠號'})
例:http_proxy_handler = urllib.request.ProxyHandler({'https':'121.43.178.58:3128'})

37.私密代理伺服器(下面的只是一個例子,不一定正確)
authproxy_handler = urllib.request.ProxyHandler({"http" : "user:password@ip:port"})

38.不使用任何代理
http_proxy_handler = urllib.request.ProxyHandler({})

39.使用了代理之後的 opener 寫法
opener = urllib.request.build_opener(http_proxy_handler)

40.response 寫法
response = opener.open(request)

41.如果訪問一個不存在的網址會報錯
urllib.error.URLError


42.HTTPError(是URLError的子類)
例:
try:
    urllib.request.urlopen(url)
except urllib.error.HTTPError as e:
    print(e.code)
    print(e.reason)
except urllib.error.URLError as e:
    print(e)

43.使用 CookieJar 建立一個 cookie 物件,儲存 cookie 值
import http.cookiejar
cookie = http.cookiejar.CookieJar()

44.通過HTTPCookieProcessor構建一個處理器物件,用來處理cookie
cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
opener 的寫法
opener = urllib.request.build_opener(cookie_handler)

45.使用 r'\x'
\d 表示轉義字元  r'\d' 表示 \d

46.設定 正則模式
pattern = re.compile(r'規則', re.xxx )
pattern = re.compile(r'i\s(.*?),')
例:pattern = re.compile(r'LOVE', re.I)

47.match 只匹配開頭字元
pattern.match('字串'[,起始位置,結束位置])
例:m = pattern.match('i love you', 2, 6)
返回值為 <re.Match object; span=(2, 6), match='love'>

48. search 從開始匹配到結尾,返回第一個匹配到的
pattern.search('字串')
例:m = pattern.search('i love you, do you love me, yes, i love')
返回值為 <re.Match object; span=(2, 6), match='love'>

49.findall 將匹配到的都放到列表中
pattern.findall('字串')
例:m = pattern.findall('i love you, do you love me, yes, i love')
返回值為 ['love', 'love', 'love']

50.split 使用匹配到的字串對原來的資料進行切割
pattern.split('字串',次數)
例:m = pattern.split('i love you, do you love me, yes, i love me', 1)
返回值為 ['i ', ' you, do you love me, yes, i love me']
例:m = pattern.split('i love you, do you love me, yes, i love me', 2)
返回值為 ['i ', ' you, do you ', ' me, yes, i love me']
例:m = pattern.split('i love you, do you love me, yes, i love me', 3)
返回值為 ['i ', ' you, do you ', ' me, yes, i ', ' me']

51.sub 使用新字串替換匹配到的字串的值,預設全部替換
pattern.sub('新字串','要匹配字串'[,次數])
注:返回的是字串
例:
string = 'i love you, do you love me, yes, i love me'
m = pattern.sub('hate', string, 1)
m 值為 'i hate you, do you love me, yes, i love me'

52.group 匹配組
m.group() 返回的是匹配都的所有字元
m.group(1) 返回的是第二個規則匹配到的字元
例:
string = 'i love you, do you love me, yes, i love me'
pattern = re.compile(r'i\s(.*?),')
m = pattern.match(string)
m.group()
返回值為 'i love you,'
m.group(1)
返回值為 'love you'

53.匹配標籤
pattern = re.compile(r'<div class="thumb">(.*?)<img src=(.*?) alt=(.*?)>(.*?)</div>', re.S)

54.分離出檔名和副檔名,返回二元組
os.path.splitext(引數)
例:
獲取路徑
image_path = './qiushi'
獲取字尾名
extension = os.path.splitext(image_url)[-1]

55.合併多個字串
os.path.join()
圖片路徑
image_path = os.path.join(image_path, image_name + extension)
儲存檔案
urllib.request.urlretrieve(image_url, image_path)

56.獲取 a 標籤下的 href 的內容
pattern = re.compile(r'<a href="(.*?)" class="main_14" target="_blank">(.*?)</a>', re.M)
例:
import urllib.parse
import urllib.request
import re

class SmileSpider(object):
    """
    爬取笑話網站笑話的排行榜
    """
    def __init__(self, url, page=1):
        super(SmileSpider, self).__init__()
        self.url = url
        self.page = page

    def handle_url(self):
        '''
        處理url並且生成request請求物件
        '''
        self.url = self.url + '?mepage=' + str(self.page)
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
        }
        request = urllib.request.Request(self.url, headers=headers)
        return request

    def xiazai(self, request):
        '''
        負責下載資料,並且將資料返回
        '''
        response = urllib.request.urlopen(request)
        html = response.read().decode('gbk')
        return html

    def handle_data(self, data):
        '''
        開始處理資料,將段子抓取出來並且寫入檔案
        '''
        # 這個必須使用多行模式進行抓取,因為是抓取多個a連結
        pattern = re.compile(r'<a href="(.*?)" class="main_14" target="_blank">(.*?)</a>', re.M)
        # 找到所有的笑話連結
        alist = pattern.findall(data)
        # print(alist)
        # exit()
        print('開始下載')
        for smile in alist:
            # 獲取標題
            # title = alist[14][1]
            title = smile[1]
            # 獲取url
            # smile_url = alist[14][0]
            smile_url = smile[0]
            # 獲取內容
            content = self.handle_content(smile_url)
            # 將抓取的這一頁的笑話寫到檔案中
            with open('xiaohua.html', 'a', encoding='gbk') as f:
                f.write('<h1>' + title + '</h1>' + content)
        print('下載完畢')

    def handle_content(self, smile_url):
        # 因為有的href中有中文,所以必須先轉碼再拼接,如果先拼接再轉碼,就會將:也給轉碼了,不符合要求
        smile_url = urllib.parse.quote(smile_url)
        smile_url = 'http://www.jokeji.cn' + smile_url
        # print(smile_url)
        # exit()
        content = self.xiazai(smile_url)

        # 由於抓取的文字中,有的中間有空格,所以使用單行模式進行抓取
        pattern = re.compile(r'<span id="text110">(.*?)</span>', re.S)
        ret = pattern.search(content)
        return ret.group(1)

    def start(self):
        request = self.handle_url()
        html = self.xiazai(request)
        self.handle_data(html)


if __name__ == '__main__':
    url = 'http://www.jokeji.cn/hot.asp'
    spider = SmileSpider(url)
    spider.start()

57.href 中有中文的需要先進行轉碼,然後再拼接
smile_url = urllib.parse.quote(smile_url)
smile_url = 'http://www.jokeji.cn' + smile_url

58.匯入 etree
from lxml import etree

59.例項化一個 html 物件,DOM模型
etree.HTML(通過requests庫的get方法或post方法獲取的資訊 其實就是 HTML 程式碼)
例:html_tree = etree.HTML(text)
返回值為 <Element html at 0x26ee35b2400>
例:type(html_tree)
<class 'lxml.etree._Element'>

60.查詢所有的 li 標籤
html_tree.xpath('//li')

61.獲取所有li下面a中屬性href為link1.html的a
result = html_tree.xpath('//標籤/標籤[@屬性="值"]')
例:result = html_tree.xpath('//li/a[@href="link.html"]')

62.獲取最後一個 li 標籤下 a 標籤下面的 href 值
result = html_tree.xpath('//li[last()]/a/@href')

63.獲取 class 為 temp 的結點
result = html_tree.xpath('//*[@class = "temp"]')

64.獲取所有 li 標籤下的 class 屬性
result = html_tree.xpath('//li/@class')

65.取出內容
[0].text
例:result = html_tree.xpath('//li[@class="popo"]/a')[0].text
例:result = html_tree.xpath('//li[@class="popo"]/a/text()')

66.將 tree 物件轉化為字串
etree.tostring(etree.HTML物件).decode('utf-8')
例:
text = '''
<div>
    <ul>
         <li class="item-0"><a href="link1.html">first item</a></li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-inactive"><a href="link3.html">third item</a></li>
         <li class="item-1"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a>
     </ul>
 </div>
'''
html = etree.HTML(text)
tostring 轉換的是bytes 型別資料
result = etree.tostring(html)
將 bytes 型別資料轉換為 str 型別資料
print(result.decode('utf-8'))

67.動態儲存圖片,使用url後幾位作為檔名
request = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(request)
html_tree = etree.HTML(html)
img_list = html_tree.xpath('//div[@class="box picblock col3"]/div/a/img/@src2')
for img_url in img_list:
    # 定製圖片名字為url後10位
    file_name = 'image/' + img_url[-10:]
    load_image(img_url, file_name)
load_image內容:
def load_image(url, file_name):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }
    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    image_bytes = response.read()

    with open(file_name, 'wb') as f:
        f.write(image_bytes)
    print(file_name + '圖片已經成功下載完畢')

例:
def load_page(url):
    headers = {
        #'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }
    print(url)
    # exit()
    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    html = response.read()

    # 這是專業的圖片網站,使用了懶載入,但是可以通過原始碼來進行檢視,並且重新寫xpath路徑
    with open('7image.html', 'w', encoding='utf-8') as f:
        f.write(html.decode('utf-8'))
    exit()

    # 將html文件解析問DOM模型
    html_tree = etree.HTML(html)
    # 通過xpath,找到需要的所有的圖片的src屬性,這裡獲取到的
    img_list = html_tree.xpath('//div[@class="box picblock col3"]/div/a/img/@src2')
    for img_url in img_list:
        # 定製圖片名字為url後10位
        file_name = 'image/' + img_url[-10:]
        load_image(img_url, file_name)

def load_image(url, file_name):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }
    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    image_bytes = response.read()

    with open(file_name, 'wb') as f:
        f.write(image_bytes)
    print(file_name + '圖片已經成功下載完畢')
def main():
    start = int(input('請輸入開始頁面:'))
    end = int(input('請輸入結束頁面:'))
    url = 'http://sc.chinaz.com/tag_tupian/'
    for page in range(start, end + 1):
        if page == 1:
            real_url = url + 'KaTong.html'
        else:
            real_url = url + 'KaTong_' + str(page) + '.html'
        load_page(real_url)
        print('' + str(page) + '頁下載完畢')

if __name__ == '__main__':
    main()

68.懶圖片載入案例
例:
import urllib.request
from lxml import etree
import json

def handle_tree(html_tree):
    node_list = html_tree.xpath('//div[@class="detail-wrapper"]')
    duan_list = []
    for node in node_list:
        # 獲取所有的使用者名稱,因為該xpath獲取的是一個span列表,然後獲取第一個,並且通過text屬性得到其內容
        user_name = node.xpath('./div[contains(@class, "header")]/a/div/span[@class="name"]')[0].text
        # 只要涉及到圖片,很有可能都是懶載入,所以要右鍵檢視網頁原始碼,才能得到真實的連結
        # 由於這個獲取的結果就是屬性字串,所以只需要加上下標0即可
        face = node.xpath('./div[contains(@class, "header")]//img/@data-src')[0]
        # .代表當前,一個/表示一級子目錄,兩個//代表當前節點裡面任意的位置查詢
        content = node.xpath('./div[@class="content-wrapper"]//p')[0].text
        zan = node.xpath('./div[@class="options"]//li[@class="digg-wrapper "]/span')[0].text
        item = {
            'username':user_name,
            'face':face,
            'content':content,
            'zan':zan,
        }
        # 將其存放到列表中
        duan_list.append(item)

    # 將列表寫入到檔案中
    with open('8duanzi.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(duan_list, ensure_ascii=False) + '\n')
    print('over')

def main():
    # 爬取百度貼吧,不能加上headers,加上headers爬取不下來
    url = 'http://neihanshequ.com/'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }
    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    html_bytes = response.read()

    # fp = open('8tieba.html', 'w', encoding='utf-8')
    # fp.write(html_bytes.decode('utf-8'))
    # fp.close()
    # exit()

    # 將html位元組串轉化為html文件樹
    # 文件樹有xpath方法,文件節點也有xpath方法 
    # 【注】不能使用位元組串轉化為文件樹,這樣會有亂碼
    html_tree = etree.HTML(html_bytes.decode('utf-8'))

    handle_tree(html_tree)


if __name__ == '__main__':
    main()

69.  . / 和 // 在 xpath 中的使用
.代表當前目錄
/ 表示一級子目錄
// 代表當前節點裡面任意的位置

70.獲取內容的示範
獲取內容時,如果為字串,則不需要使用 text 只需要寫[0]
face = node.xpath('./div[contains(@class, "header")]//img/@data-src')[0]
div 下 class"content-wrapper" 的所有 p 標籤內容
content = node.xpath('./div[@class="content-wrapper"]//p')[0].text
div 下 class"options" 的所有 li 標籤下 class為 "digg-wrapper" 的所有 span 標籤內容
zan = node.xpath('./div[@class="options"]//li[@class="digg-wrapper"]/span')[0].text

71.將json物件轉化為json格式字串
f.write(json.dumps(duan_list, ensure_ascii=False) + '\n')

72.正則獲取 div 下的內容
1.獲取 div 到 img 之間的資料
2.img 下 src 的資料
3.img 下 alt 的資料
4.一直到 div 結束的資料
pattern = re.compile(r'<div class="thumb">(.*?)<img src=(.*?) alt=(.*?)>(.*?)</div>', re.S)
pattern.方法 ,參考上面的正則

73.帶有引數的 get 方式
import requests
params = {
    'wd':'中國'
}
r = requests.get('http://www.baidu.com/s?', headers=headers, params=params)
    requests.get 還可以新增 cookie 引數

74.設定編碼
r.encoding='utf-8

75.檢視所有頭資訊
r.request.headers

76.在 requests.get 方法中 url,params,headers,proxies 為引數
url 網址  params 需要的資料 headers 頭部 proxies 代理

77.通過 Session 物件,傳送請求
s = requests.Session()

78.傳送請求
s.post(url,data,headers)

79.接收請求
s.get(url[,proxies])

80.當返回為 json 樣式時
例:
city = input('請輸入要查詢的城市:')
params = {
    'city':city
}
r = requests.get(url, params=params)
r.json() 會打印出響應的內容

81.BeautifulSoup 建立物件
from bs4 import BeautifulSoup
soup = BeautifulSoup(open(url,encoding='utf-8),'lxml')

82.查詢第一個<title> 標籤
soup.title
返回值為 <title>三國猛將</title>

83.查詢第一個 a 標籤
soup.a
返回值為 <a class="aa" href="http://www.baidu.com" title="baidu">百度</a>

84.查詢第一個 ul 標籤
soup.ul

85.檢視標籤名字
a_tag = soup.a
a_tag.name
返回值為 a

86.檢視標籤內容
a_tag.attrs
返回值為 {'href': 'http://www.baidu.com', 'title': 'baidu', 'class': ['aa']}

87.獲取找到的 a 標籤的 href 內容(第一個 a)
soup.a.get('href')
返回值為 http://www.baidu.com

88.獲取 a 標籤下的 title 屬性(第一個 a)
soup.a.get('title')
返回值為 baidu

89.檢視 a 標籤下的內容
soup.標籤.string 標籤還可以是 head、title等
soup.a.string
返回值為 百度

90.獲取 p 標籤下的內容
soup.p.string

91.檢視 div 的內容,包含 '\n'
soup.div.contents
返回值為
['\n', <div class="div">
<a class="la" href="www.nihao.com">你好</a>
</div>, '\n', <div>
<a href="www.hello.com">世界</a>
</div>, '\n']

92.檢視使用的字符集
soup.div.contents[1]
返回值為 <meta charset="utf-8"/>

93.檢視body的子節點
soup.標籤.children
例:soup.body.children
返回值是一個迭代物件,需要遍歷輸出
返回值為 <list_iterator object at 0x0000021863886C10>
for child in soup.body.children:
    print(child)
返回值為 body 中的所有內容

94.檢視所有的子孫節點
soup.標籤.descendants
例:soup.div.descendants
返回值為
<div class="div">
<a class="la" href="www.nihao.com">你好</a>
</div>
<a class="la" href="www.nihao.com">你好</a>
你好

95.檢視所有的 a 標籤
soup.find_all('a')
返回值為 包含所有的 a 標籤的列表

96.檢視 a 標籤中第二個連結的內容
soup.find_all('a')[1].string

97.檢視 a 標籤中第二個連結的href值
soup.find_all('a')[1].href

98.將 re 正則嵌入進來,找尋所有以 b 開頭的標籤
soup.findall(re.compile('^b'))
返回值為 <body>標籤 <b>

99.找到所有的 a 標籤和 b 標籤
soup.findall(re.compile(['a','b']))
返回值為 <a> 和 <b> 標籤

100.通過標籤名獲取所有的 a 標籤
soup.select('a')
返回值為 所有的 <a> 標籤

101.通過 類名 獲取標籤(在 class 等於的值前面加 .)
soup.select('.aa')
返回值為 class='aa' 的標籤

102.通過 id 名獲取標籤(在 id 等於的值前面加 #)
soup.select('#wangyi')
返回值為 id='wangyi'的標籤

103.檢視 div 下 class='aa' 的標籤
soup.select('標籤 .class 等於的值')
soup.select('div .aa')

104.檢視 div 下,第一層 class='aa' 的標籤
soup.select('.標籤名 > .class= 的值')
soup.select('.div > .la')

105.根據屬性進行查詢,input 標籤下class為 haha 的標籤
soup.select('input[class="haha"]')

例:
import requests
from bs4 import BeautifulSoup
import json
import lxml

def load_url(jl, kw):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }

    url = 'http://sou.zhaopin.com/jobs/searchresult.ashx?'
    params = {
        'jl':jl,
        'kw':kw,
    }
    # 自動完成轉碼,直接使用即可
    r = requests.get(url, params=params, headers=headers)

    handle_data(r.text)

def handle_data(html):
    # 建立soup物件
    soup = BeautifulSoup(html, 'lxml')
    # 查詢職位名稱
    job_list = soup.select('#newlist_list_content_table table')
    # print(job_list)
    jobs = []
    i = 1
    for job in job_list:
        # 因為第一個table只是表格的標題,所以要過濾掉
        if i == 1:
            i = 0
            continue
        item = {}
        # 公司名稱
        job_name = job.select('.zwmc div a')[0].get_text()

        # 職位月薪
        company_name = job.select('.gsmc a')[0].get_text()
        # 工作地點
        area = job.select('.gzdd')[0].get_text()

        # 釋出日期
        time = job.select('.gxsj span')[0].get_text()
        # 將所有資訊新增到字典中
        item['job_name'] = job_name
        item['company_name'] = company_name
        item['area'] = area
        item['time'] = time
        jobs.append(item)

    # 將列表轉化為json格式字串,然後寫入到檔案中
    content = json.dumps(jobs, ensure_ascii=False)
    with open('python.json', 'w', encoding='utf-8') as f:
        f.write(content)
    print('over')

def main():
    # jl = input('請輸入工作地址:')
    # kw = input('請輸入工作職位:')
    load_url(jl='北京', kw='python')

if __name__ == '__main__':
    main()

106.將字典進行 json 轉換為
import json
str_dict = {"name":"張三", "age":55, "height":180}
print(json.dumps(str_dict, ensure_ascii=False))
使用 ensure_ascii 輸出則為 utf-8 編碼

107.讀取轉換的物件,(注意 loads 和 load 方法)
json.loads(json.dumps 物件)
string = json.dumps(str_dict, ensure_ascii=False)
json.loads(string)
{"name":"張三", "age":55, "height":180}

108.將物件序列化之後寫入檔案
json.dump(字典物件,open(檔名.json,'w',encoding='utf-8,ensure_ascii=False))
json.dump(str_dict, open('jsontest.json', 'w', encoding='utf-8'), ensure_ascii=False)

109.轉換本地的 json 檔案轉換為 python 物件
json.load(open('檔名.json',encoding='utf-8))

110.jsonpath 示例:
book.json檔案
{
    "store": {
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95
            },
            {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 12.99
            },
            {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 8.99
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "isbn": "0-395-19395-8",
                "price": 22.99
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    }
}

import json
import jsonpath

obj = json.load(open('book.json', encoding='utf-8'))

所有book
book = jsonpath.jsonpath(obj, '$..book')
print(book)

所有book中的所有作者
authors = jsonpath.jsonpath(obj, '$..book..author')
print(authors)

book中的前兩本書   '$..book[:2]'
book中的最後兩本書 '$..book[-2:]'
book = jsonpath.jsonpath(obj, '$..book[0,1]')
print(book)

所有book中,有屬性isbn的書籍
book = jsonpath.jsonpath(obj, '$..book[?(@.isbn)]')
print(book)

所有book中,價格小於10的書籍
book = jsonpath.jsonpath(obj, '$.store.book[?(@.price<10)]')
print(book)

numpy第三方庫
# 匯入numpy 並賦予別名 np
import numpy as np
# 建立陣列的常用的幾種方式(列表,元組,range,arange,linspace(建立的是等差陣列),zeros(全為 0 的陣列),ones(全為 1 的陣列),logspace(建立的是對數陣列))
# 列表方式
np.array([1,2,3,4])
# array([1, 2, 3, 4])

# 元組方式
np.array((1,2,3,4))
# array([1, 2, 3, 4])

# range 方式
np.array(range(4)) # 不包含終止數字
# array([0, 1, 2, 3])

# 使用 arange(初始位置=0,末尾,步長=1)
    # 不包含末尾元素
np.arange(1,8,2)
# array([1, 3, 5, 7])

np.arange(8)
# array([0, 1, 2, 3, 4, 5, 6, 7])
# 使用 linspace(起始數字,終止數字,包含數字的個數[,endpoint = False]) 生成等差陣列

# 生成等差陣列,endpoint 為 True 則包含末尾數字
np.linspace(1,3,4,endpoint=False)
# array([1. , 1.5, 2. , 2.5])
np.linspace(1,3,4,endpoint=True)
# array([1.        , 1.66666667, 2.33333333, 3.        ])

# 建立全為零的一維陣列
np.zeros(3)
# 建立全為一的一維陣列
np.ones(4)
# array([1., 1., 1., 1.])

np.linspace(1,3,4)
# array([1.        , 1.66666667, 2.33333333, 3.        ])

# np.logspace(起始數字,終止數字,數字個數,base = 10) 對數陣列
np.logspace(1,3,4)
# 相當於 10 的 linspace(1,3,4) 次方
# array([  10.        ,   46.41588834,  215.443469  , 1000.        ])
np.logspace(1,3,4,base = 2)
# array([2.       , 3.1748021, 5.0396842, 8.       ])


# 建立二維陣列(列表巢狀列表)
np.array([[1,2,3],[4,5,6]])
'''
array([[1, 2, 3],
       [4, 5, 6]])
'''

# 建立全為零的二維陣列
# 兩行兩列
np.zeros((2,2))
'''
array([[0., 0.],
       [0., 0.]])
'''
# 三行三列
np.zeros((3,2))
'''
array([[0., 0.],
       [0., 0.],
       [0., 0.]])
'''

# 建立一個單位陣列
np.identity(3)
'''
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
'''
# 建立一個對角矩陣,(引數為對角線上的數字)
np.diag((1,2,3))
'''
array([[1, 0, 0],
       [0, 2, 0],
       [0, 0, 3]])
'''

import numpy as np
x = np.arange(8)
# [0 1 2 3 4 5 6 7]
# 在陣列尾部追加一個元素
np.append(x,10)
# array([ 0,  1,  2,  3,  4,  5,  6,  7, 10])

# 在陣列尾部追加多個元素
np.append(x,[15,16,17])
# array([ 0,  1,  2,  3,  4,  5,  6,  7, 15, 16, 17])

# 使用 陣列下標修改元素的值
x[0] = 99
# array([99,  1,  2,  3,  4,  5,  6,  7])

# 在指定位置插入資料
np.insert(x,0,54)
# array([54, 99,  1,  2,  3,  4,  5,  6,  7])

# 建立一個多維陣列
x = np.array([[1,2,3],[11,22,33],[111,222,333]])
'''
array([[  1,   2,   3],
       [ 11,  22,  33],
       [111, 222, 333]])
'''
# 修改第 0 行第 2 列的元素值
x[0,2] = 9
'''
array([[  1,   2,   9],
       [ 11,  22,  33],
       [111, 222, 333]])
'''
# 行數大於等於 1 的,列數大於等於 1 的置為 1
x[1:,1:] = 1
'''
array([[  1,   2,   9],
       [ 11,   1,   1],
       [111,   1,   1]])
'''
# 同時修改多個元素值
x[1:,1:] = [7,8]
'''
array([[  1,   2,   9],
       [ 11,   7,   8],
       [111,   7,   8]])
'''
x[1:,1:] = [[7,8],[9,10]]
'''
array([[  1,   2,   9],
       [ 11,   7,   8],
       [111,   9,  10]])
'''

import numpy as np
n = np.arange(10)
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

# 檢視陣列的大小
n.size
# 10

# 將陣列分為兩行五列
n.shape = 2,5
'''
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
'''
# 顯示陣列的維度
n.shape
# (2, 5)

# 設定陣列的維度,-1 表示自動計算
n.shape = 5,-1
'''
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7],
       [8, 9]])
'''
# 將新陣列設定為呼叫陣列的兩行五列並返回
x = n.reshape(2,5)
'''
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
'''
x = np.arange(5)
# 將陣列設定為兩行,沒有數的設定為 0
x.resize((2,10))
'''
array([[0, 1, 2, 3, 4, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
'''
# 將 x 陣列的兩行五列形式顯示,不改變 x 的值
np.resize(x,(2,5))
'''
array([[0, 1, 2, 3, 4],
       [0, 0, 0, 0, 0]])
'''

import numpy as np
n = np.array(([1,2,3],[4,5,6],[7,8,9]))
'''
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
'''
# 第一行元素
n[0]
# array([1, 2, 3])

# 第一行第三列元素
n[0,2]
# 3

# 第一行和第二行的元素
n[[0,1]]
'''
array([[1, 2, 3],
       [4, 5, 6]])
'''
# 第一行第三列,第三行第二列,第二行第一列
n[[0,2,1],[2,1,0]]
# array([3, 8, 4])

a = np.arange(8)
# array([0, 1, 2, 3, 4, 5, 6, 7])

# 將陣列倒序
a[::-1]
# array([7, 6, 5, 4, 3, 2, 1, 0])

# 步長為 2
a[::2]
# array([0, 2, 4, 6])

# 從 0 到 4 的元素
a[:5]
# array([0, 1, 2, 3, 4])


c = np.arange(16)
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
c.shape = 4,4
'''
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
'''

# 第一行,第三個元素到第五個元素(如果沒有則輸出到末尾截止)
c[0,2:5]
# array([2, 3])

# 第二行元素
c[1]
# array([4, 5, 6, 7])

# 第三行到第六行,第三列到第六列
c[2:5,2:5]
'''
array([[10, 11],
       [14, 15]])
'''
# 第二行第三列元素和第三行第四列元素
c[[1,2],[2,3]]
# array([ 6, 11])

# 第一行和第三行的第二列到第三列的元素
c[[0,2],1:3]
'''
array([[ 1,  2],
       [ 9, 10]])
'''
# 第一列和第三列的所有橫行元素
c[:,[0,2]]
'''
array([[ 0,  2],
       [ 4,  6],
       [ 8, 10],
       [12, 14]])
'''
# 第三列所有元素
c[:,2]
# array([ 2,  6, 10, 14])

# 第二行和第四行的所有元素
c[[1,3]]
'''
array([[ 4,  5,  6,  7],
       [12, 13, 14, 15]])
'''
# 第一行的第二列,第四列元素,第四行的第二列,第四列元素
c[[0,3]][:,[1,3]]
'''
array([[ 1,  3],
       [13, 15]])
'''

import numpy as np
x = np.array((1,2,3,4,5))

# 使用 * 進行相乘
x*2
# array([ 2,  4,  6,  8, 10])

# 使用 / 進行相除
x / 2
# array([0.5, 1. , 1.5, 2. , 2.5])
2 / x
# array([2.        , 1.        , 0.66666667, 0.5       , 0.4       ])

# 使用 // 進行整除
x//2
# array([0, 1, 1, 2, 2], dtype=int32)
10//x
# array([10,  5,  3,  2,  2], dtype=int32)


# 使用 ** 進行冪運算
x**3
# array([  1,   8,  27,  64, 125], dtype=int32)

2 ** x
# array([ 2,  4,  8, 16, 32], dtype=int32)


# 使用 + 進行相加
x + 2
# array([3, 4, 5, 6, 7])

# 使用 % 進行取模
x % 3
# array([1, 2, 0, 1, 2], dtype=int32)

# 陣列與陣列之間的運算
# 使用 + 進行相加
np.array([1,2,3,4]) + np.array([11,22,33,44])
# array([12, 24, 36, 48])

np.array([1,2,3,4]) + np.array([3])
# array([4, 5, 6, 7])

n = np.array((1,2,3))
# +
n + n
# array([2, 4, 6])
n + np.array([4])
# array([5, 6, 7])

# *
n * n
# array([1, 4, 9])
n * np.array(([1,2,3],[4,5,6],[7,8,9]))
'''
array([[ 1,  4,  9],
       [ 4, 10, 18],
       [ 7, 16, 27]])
'''

# -
n - n
# array([0, 0, 0])

# /
n/n
# array([1., 1., 1.])

# **
n**n
# array([ 1,  4, 27], dtype=int32)


x = np.array((1,2,3))
y = np.array((4,5,6))
# 陣列的內積運算(對應位置上元素相乘)
np.dot(x,y)
# 32
sum(x*y)
# 32

# 布林運算
n = np.random.rand(4)
# array([0.53583849, 0.09401473, 0.07829069, 0.09363152])

# 判斷陣列中的元素是否大於 0.5
n > 0.5
# array([ True, False, False, False])

# 將陣列中大於 0.5 的元素顯示
n[n>0.5]
# array([0.53583849])

# 找到陣列中 0.05 ~ 0.4 的元素總數
sum((n > 0.05)&(n < 0.4))
# 3

# 是否都大於 0.2
np.all(n > 0.2)
# False

# 是否有元素小於 0.1
np.any(n < 0.1)
# True

# 陣列與陣列之間的布林運算
a = np.array([1,4,7])
# array([1, 4, 7])
b = np.array([4,3,7])
# array([4, 3, 7])

# 在 a 中是否有大於 b 的元素
a > b
# array([False,  True, False])

# 在 a 中是否有等於 b 的元素
a == b
# array([False, False,  True])

# 顯示 a 中 a 的元素等於 b 的元素
a[a == b]
# array([7])

# 顯示 a 中的偶數且小於 5 的元素
a[(a%2 == 0) & (a < 5)]
# array([4])

import numpy as np
# 將 0~100 10等分
x = np.arange(0,100,10)
# array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])

# 每個陣列元素對應的正弦值
np.sin(x)
'''
array([ 0.        , -0.54402111,  0.91294525, -0.98803162,  0.74511316,
       -0.26237485, -0.30481062,  0.77389068, -0.99388865,  0.89399666])
'''
# 每個陣列元素對應的餘弦值
np.cos(x)
'''
array([ 1.        , -0.83907153,  0.40808206,  0.15425145, -0.66693806,
        0.96496603, -0.95241298,  0.6333192 , -0.11038724, -0.44807362])
'''
# 對引數進行四捨五入
np.round(np.cos(x))
# array([ 1., -1.,  0.,  0., -1.,  1., -1.,  1., -0., -0.])

# 對引數進行上入整數 3.3->4
np.ceil(x/3)
# array([ 0.,  4.,  7., 10., 14., 17., 20., 24., 27., 30.])


# 分段函式
x = np.random.randint(0,10,size=(1,10))
# array([[0, 3, 6, 7, 9, 4, 9, 8, 1, 8]])

# 大於 4 的置為 0
np.where(x > 4,0,1)
# array([[1, 1, 0, 0, 0, 1, 0, 0, 1, 0]])

# 小於 4 的乘 2 ,大於 7 的乘3
np.piecewise(x,[x<4,x>7],[lambda x:x*2,lambda x:x*3])
# array([[ 0,  6,  0,  0, 27,  0, 27, 24,  2, 24]])


import numpy as np
x = np.array([1,4,5,2])
# array([1, 4, 5, 2])

# 返回排序後元素的原下標
np.argsort(x)
# array([0, 3, 1, 2], dtype=int64)

# 輸出最大值的下標
x.argmax( )
# 2

# 輸出最小值的下標
x.argmin( )
# 0

# 對陣列進行排序
x.sort( )

import numpy as np
# 生成一個隨機陣列
np.random.randint(0,6,3)
# array([1, 1, 3])

# 生成一個隨機陣列(二維陣列)
np.random.randint(0,6,(3,3))
'''
array([[4, 4, 1],
       [2, 1, 0],
       [5, 0, 0]])
'''
# 生成十個隨機數在[0,1)之間
np.random.rand(10)
'''
array([0.9283789 , 0.43515554, 0.27117021, 0.94829333, 0.31733981,
       0.42314939, 0.81838647, 0.39091899, 0.33571004, 0.90240897])
'''
# 從標準正態分佈中隨機抽選出3個數
np.random.standard_normal(3)
# array([0.34660435, 0.63543859, 0.1307822 ])
# 返回三頁四行兩列的標準正態分佈數
np.random.standard_normal((3,4,2))
'''
array([[[-0.24880261, -1.17453957],
        [ 0.0295264 ,  1.04038047],
        [-1.45201783,  0.57672288],
        [ 1.10282747, -2.08699482]],

       [[-0.3813943 ,  0.47845782],
        [ 0.97708005,  1.1760147 ],
        [ 1.3414987 , -0.629902  ],
        [-0.29780567,  0.60288726]],

       [[ 1.43991349, -1.6757028 ],
        [-1.97956809, -1.18713495],
        [-1.39662811,  0.34174275],
        [ 0.56457553, -0.83224426]]])
'''
# 建立矩陣
import numpy as np
x = np.matrix([[1,2,3],[4,5,6]])
'''
matrix([[1, 2, 3],
        [4, 5, 6]])
'''
y = np.matrix([1,2,3,4,5,6])
# matrix([[1, 2, 3, 4, 5, 6]])

# x 的第二行第二列元素
x[1,1]
# 5

# 矩陣的函式
import numpy as np
# 矩陣的轉置
x = np.matrix([[1,2,3],[4,5,6]])
'''
matrix([[1, 2, 3],
        [4, 5, 6]])
'''
y = np.matrix([1,2,3,4,5,6])
# matrix([[1, 2, 3, 4, 5, 6]])

# 實現矩陣的轉置
x.T
'''
matrix([[1, 4],
        [2, 5],
        [3, 6]])
'''
y.T
'''
matrix([[1],
        [2],
        [3],
        [4],
        [5],
        [6]])
'''
# 元素平均值
x.mean()
# 3.5

# 縱向平均值
x.mean(axis = 0)
# matrix([[2.5, 3.5, 4.5]])

# 橫向平均值
x.mean(axis = 1)
'''
matrix([[2.],
        [5.]])
'''

# 所有元素之和
x.sum()
# 21

# 橫向最大值
x.max(axis = 1)
'''
matrix([[3],
        [6]])
'''
# 橫向最大值的索引下標
x.argmax(axis = 1)
'''
matrix([[2],
        [2]], dtype=int64)
'''

# 對角線元素
x.diagonal()
# matrix([[1, 5]])

# 非零元素下標
x.nonzero()
# (array([0, 0, 0, 1, 1, 1], dtype=int64),
# array([0, 1, 2, 0, 1, 2], dtype=int64))


# 矩陣的運算
import numpy as np
x = np.matrix([[1,2,3],[4,5,6]])
'''
matrix([[1, 2, 3],
        [4, 5, 6]])
'''
y = np.matrix([[1,2],[4,5],[7,8]])
'''
matrix([[1, 2],
        [4, 5],
        [7, 8]])
'''
# 矩陣的乘法
x*y
'''
matrix([[30, 36],
        [66, 81]])
'''
# 相關係數矩陣,可使用在列表元素陣列矩陣
# 負相關
np.corrcoef([1,2,3],[8,5,4])
'''
array([[ 1.        , -0.96076892],
       [-0.96076892,  1.        ]])
'''
# 正相關
np.corrcoef([1,2,3],[4,5,7])
'''
array([[1.        , 0.98198051],
       [0.98198051, 1.        ]])
'''
# 矩陣的方差
np.cov([1,1,1,1,1])
# array(0.)

# 矩陣的標準差
np.std([1,1,1,1,1])
# 0.0

x = [-2.1,-1,4.3]
y = [3,1.1,0.12]

# 垂直堆疊矩陣
z = np.vstack((x,y))
'''
array([[-2.1 , -1.  ,  4.3 ],
       [ 3.  ,  1.1 ,  0.12]])
'''
# 矩陣的協方差
np.cov(z)
'''
array([[11.71      , -4.286     ],
       [-4.286     ,  2.14413333]])
'''
np.cov(x,y)
'''
array([[11.71      , -4.286     ],
       [-4.286     ,  2.14413333]])
'''
# 標準差
np.std(z)
# 2.2071223094538484

# 列向標準差
np.std(z,axis = 1)
# array([2.79404128, 1.19558447])

# 方差
np.cov(x)
# array(11.71)

# 特徵值和特徵向量
A = np.array([[1,-3,3],[3,-5,3],[6,-6,4]])
'''
array([[ 1, -3,  3],
       [ 3, -5,  3],
       [ 6, -6,  4]])
'''
e,v = np.linalg.eig(A)
# e 為特徵值, v 為特徵向量
'''
e
    array([ 4.+0.00000000e+00j, -2.+1.10465796e-15j, -2.-1.10465796e-15j])
v
    array([[-0.40824829+0.j        ,  0.24400118-0.40702229j,
         0.24400118+0.40702229j],
       [-0.40824829+0.j        , -0.41621909-0.40702229j,
        -0.41621909+0.40702229j],
       [-0.81649658+0.j        , -0.66022027+0.j        ,
        -0.66022027-0.j        ]])
'''
# 矩陣與特徵向量的乘積
np.dot(A,v)
'''
array([[-1.63299316+0.00000000e+00j, -0.48800237+8.14044580e-01j,
        -0.48800237-8.14044580e-01j],
       [-1.63299316+0.00000000e+00j,  0.83243817+8.14044580e-01j,
         0.83243817-8.14044580e-01j],
       [-3.26598632+0.00000000e+00j,  1.32044054-5.55111512e-16j,
         1.32044054+5.55111512e-16j]])
'''
# 特徵值與特徵向量的乘積
e * v
'''
array([[-1.63299316+0.00000000e+00j, -0.48800237+8.14044580e-01j,
        -0.48800237-8.14044580e-01j],
       [-1.63299316+0.00000000e+00j,  0.83243817+8.14044580e-01j,
         0.83243817-8.14044580e-01j],
       [-3.26598632+0.00000000e+00j,  1.32044054-7.29317578e-16j,
         1.32044054+7.29317578e-16j]])
'''
# 驗證兩個乘積是否相等
np.isclose(np.dot(A,v),(e * v))
'''
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]])
'''
# 行列式 |A - λE| 的值應為 0
np.linalg.det(A-np.eye(3,3)*e)
# 5.965152994198125e-14j


x = np.matrix([[1,2,3],[4,5,6],[7,8,0]])
'''
matrix([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 0]])
'''
# 逆矩陣
y = np.linalg.inv(x)
'''

matrix([[-1.77777778,  0.88888889, -0.11111111],
        [ 1.55555556, -0.77777778,  0.22222222],
        [-0.11111111,  0.22222222, -0.11111111]])
注:numpy.linalg.LinAlgError: Singular matrix 矩陣不存在逆矩陣
'''
# 矩陣的乘法
x * y
'''
matrix([[ 1.00000000e+00,  5.55111512e-17,  1.38777878e-17],
        [ 5.55111512e-17,  1.00000000e+00,  2.77555756e-17],
        [ 1.77635684e-15, -8.88178420e-16,  1.00000000e+00]])
'''
y * x
'''
matrix([[ 1.00000000e+00, -1.11022302e-16,  0.00000000e+00],
        [ 8.32667268e-17,  1.00000000e+00,  2.22044605e-16],
        [ 6.93889390e-17,  0.00000000e+00,  1.00000000e+00]])
'''
# 求解線性方程組
a = np.array([[3,1],[1,2]])
'''
array([[3, 1],
       [1, 2]])
'''
b = np.array([9,8])
# array([9, 8])

# 求解
x = np.linalg.solve(a,b)
# array([2., 3.])

# 驗證
np.dot(a,x)
# array([9., 8.])

# 最小二乘解:返回解,餘項,a 的秩,a 的奇異值
np.linalg.lstsq(a,b)
# (array([2., 3.]), array([], dtype=float64), 2, array([3.61803399, 1.38196601]))

# 計算向量和矩陣的範數
x = np.matrix([[1,2],[3,-4]])
'''
matrix([[ 1,  2],
        [ 3, -4]])
'''
np.linalg.norm(x)
# 5.477225575051661
np.linalg.norm(x,-2)
# 1.9543950758485487
np.linalg.norm(x,-1)
# 4.0
np.linalg.norm(x,1)
# 6.0
np.linalg.norm([1,2,0,3,4,0],0)
# 4.0
np.linalg.norm([1,2,0,3,4,0],2)
# 5.477225575051661

# 奇異值分解
a = np.matrix([[1,2,3],[4,5,6],[7,8,9]])
'''
matrix([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]])
'''
u,s,v = np.linalg.svd(a)
u
'''
matrix([[-0.21483724,  0.88723069,  0.40824829],
        [-0.52058739,  0.24964395, -0.81649658],
        [-0.82633754, -0.38794278,  0.40824829]])
'''
s
'''
array([1.68481034e+01, 1.06836951e+00, 4.41842475e-16])
'''
v
'''
matrix([[-0.47967118, -0.57236779, -0.66506441],
        [-0.77669099, -0.07568647,  0.62531805],
        [-0.40824829,  0.81649658, -0.40824829]])
'''
# 驗證
u * np.diag(s) * v
'''
matrix([[1., 2., 3.],
        [4., 5., 6.],
        [7., 8., 9.]])
'''

pandas第三方庫
# 一維陣列與常用操作
import pandas as pd

# 設定輸出結果列對齊
pd.set_option('display.unicode.ambiguous_as_wide',True)
pd.set_option('display.unicode.east_asian_width',True)

# 建立 從 0 開始的非負整數索引
s1 = pd.Series(range(1,20,5))
'''
0     1
1     6
2    11
3    16
dtype: int64
'''
# 使用字典建立 Series 字典的鍵作為索引
s2 = pd.Series({'語文':95,'數學':98,'Python':100,'物理':97,'化學':99})
'''
語文       95
數學       98
Python    100
物理       97
化學       99
dtype: int64
'''
# 修改 Series 物件的值
s1[3] = -17
'''
0     1
1     6
2    11
3   -17
dtype: int64
'''
s2['語文'] = 94
'''
語文       94
數學       98
Python    100
物理       97
化學       99
dtype: int64
'''
# 檢視 s1 的絕對值
abs(s1)
'''
0     1
1     6
2    11
3    17
dtype: int64
'''
# 將 s1 所有的值都加 5
s1 + 5
'''
0     6
1    11
2    16
3   -12
dtype: int64
'''
# 在 s1 的索引下標前加入引數值
s1.add_prefix(2)
'''
20     1
21     6
22    11
23   -17
dtype: int64
'''
# s2 資料的直方圖
s2.hist()

# 每行索引後面加上 hany
s2.add_suffix('hany')
'''
語文hany       94
數學hany       98
Pythonhany    100
物理hany       97
化學hany       99
dtype: int64
'''
# 檢視 s2 中最大值的索引
s2.argmax()
# 'Python'

# 檢視 s2 的值是否在指定區間內
s2.between(90,100,inclusive = True)
'''
語文      True
數學      True
Python    True
物理      True
化學      True
dtype: bool
'''
# 檢視 s2 中 97 分以上的資料
s2[s2 > 97]
'''
數學       98
Python    100
化學       99
dtype: int64
'''
# 檢視 s2 中大於中值的資料
s2[s2 > s2.median()]
'''
Python    100
化學       99
dtype: int64
'''
# s2 與數字之間的運算,開平方 * 10 保留一位小數
round((s2**0.5)*10,1)
'''
語文       97.0
數學       99.0
Python    100.0
物理       98.5
化學       99.5
dtype: float64
'''
# s2 的中值
s2.median()
# 98.0

# s2 中最小的兩個數
s2.nsmallest(2)
'''
語文    94
物理    97
dtype: int64
'''
# s2 中最大的兩個數
s2.nlargest(2)
'''
Python    100
化學       99
dtype: int64
'''
# Series 物件之間的運算,對相同索引進行計算,不是相同索引的使用 NaN
pd.Series(range(5)) + pd.Series(range(5,10))
'''
0     5
1     7
2     9
3    11
4    13
dtype: int64
'''
# pipe 對 Series 物件使用匿名函式
pd.Series(range(5)).pipe(lambda x,y,z :(x**y)%z,2,5)
'''
0    0
1    1
2    4
3    4
4    1
dtype: int64
'''
pd.Series(range(5)).pipe(lambda x:x+3)
'''
0    3
1    4
2    5
3    6
4    7
dtype: int64
'''
pd.Series(range(5)).pipe(lambda x:x+3).pipe(lambda x:x*3)
'''
0     9
1    12
2    15
3    18
4    21
dtype: int64
'''
# 對 Series 物件使用匿名函式
pd.Series(range(5)).apply(lambda x:x+3)
'''
0    3
1    4
2    5
3    6
4    7
dtype: int64
'''
# 檢視標準差
pd.Series(range(0,5)).std()
# 1.5811388300841898

# 檢視無偏方差
pd.Series(range(0,5)).var()
# 2.5

# 檢視無偏標準差
pd.Series(range(0,5)).sem()
# 0.7071067811865476

# 檢視是否存在等價於 True 的值
any(pd.Series([3,0,True]))
# True

# 檢視是否所有的值都等價於 True
all(pd.Series([3,0,True]))
# False

# 時間序列和常用操作
import pandas as pd

# 每隔五天--5D
pd.date_range(start = '20200101',end = '20200131',freq = '5D')
'''
DatetimeIndex(['2020-01-01', '2020-01-06', '2020-01-11', '2020-01-16',
               '2020-01-21', '2020-01-26', '2020-01-31'],
              dtype='datetime64[ns]', freq='5D')
'''
# 每隔一週--W
pd.date_range(start = '20200301',end = '20200331',freq = 'W')
'''
DatetimeIndex(['2020-03-01', '2020-03-08', '2020-03-15', '2020-03-22',
               '2020-03-29'],
              dtype='datetime64[ns]', freq='W-SUN')
'''
# 間隔兩天,五個資料
pd.date_range(start = '20200301',periods = 5,freq = '2D')
'''
DatetimeIndex(['2020-03-01', '2020-03-03', '2020-03-05', '2020-03-07',
               '2020-03-09'],
              dtype='datetime64[ns]', freq='2D')
'''
# 間隔三小時,八個資料
pd.date_range(start = '20200301',periods = 8,freq = '3H')
'''
DatetimeIndex(['2020-03-01 00:00:00', '2020-03-01 03:00:00',
               '2020-03-01 06:00:00', '2020-03-01 09:00:00',
               '2020-03-01 12:00:00', '2020-03-01 15:00:00',
               '2020-03-01 18:00:00', '2020-03-01 21:00:00'],
              dtype='datetime64[ns]', freq='3H')
'''
# 三點開始,十二個資料,間隔一分鐘
pd.date_range(start = '202003010300',periods = 12,freq = 'T')
'''
DatetimeIndex(['2020-03-01 03:00:00', '2020-03-01 03:01:00',
               '2020-03-01 03:02:00', '2020-03-01 03:03:00',
               '2020-03-01 03:04:00', '2020-03-01 03:05:00',
               '2020-03-01 03:06:00', '2020-03-01 03:07:00',
               '2020-03-01 03:08:00', '2020-03-01 03:09:00',
               '2020-03-01 03:10:00', '2020-03-01 03:11:00'],
              dtype='datetime64[ns]', freq='T')
'''
# 每個月的最後一天
pd.date_range(start = '20190101',end = '20191231',freq = 'M')
'''
DatetimeIndex(['2019-01-31', '2019-02-28', '2019-03-31', '2019-04-30',
               '2019-05-31', '2019-06-30', '2019-07-31', '2019-08-31',
               '2019-09-30', '2019-10-31', '2019-11-30', '2019-12-31'],
              dtype='datetime64[ns]', freq='M')
'''
# 間隔一年,六個資料,年末最後一天
pd.date_range(start = '20190101',periods = 6,freq = 'A')
'''
DatetimeIndex(['2019-12-31', '2020-12-31', '2021-12-31', '2022-12-31',
               '2023-12-31', '2024-12-31'],
              dtype='datetime64[ns]', freq='A-DEC')
'''
# 間隔一年,六個資料,年初最後一天
pd.date_range(start = '20200101',periods = 6,freq = 'AS')
'''
DatetimeIndex(['2020-01-01', '2021-01-01', '2022-01-01', '2023-01-01',
               '2024-01-01', '2025-01-01'],
              dtype='datetime64[ns]', freq='AS-JAN')
'''
# 使用 Series 物件包含時間序列物件,使用特定索引
data = pd.Series(index = pd.date_range(start = '20200321',periods = 24,freq = 'H'),data = range(24))
'''
2020-03-21 00:00:00     0
2020-03-21 01:00:00     1
2020-03-21 02:00:00     2
2020-03-21 03:00:00     3
2020-03-21 04:00:00     4
2020-03-21 05:00:00     5
2020-03-21 06:00:00     6
2020-03-21 07:00:00     7
2020-03-21 08:00:00     8
2020-03-21 09:00:00     9
2020-03-21 10:00:00    10
2020-03-21 11:00:00    11
2020-03-21 12:00:00    12
2020-03-21 13:00:00    13
2020-03-21 14:00:00    14
2020-03-21 15:00:00    15
2020-03-21 16:00:00    16
2020-03-21 17:00:00    17
2020-03-21 18:00:00    18
2020-03-21 19:00:00    19
2020-03-21 20:00:00    20
2020-03-21 21:00:00    21
2020-03-21 22:00:00    22
2020-03-21 23:00:00    23
Freq: H, dtype: int64
'''
# 檢視前五個資料
data[:5]
'''
2020-03-21 00:00:00    0
2020-03-21 01:00:00    1
2020-03-21 02:00:00    2
2020-03-21 03:00:00    3
2020-03-21 04:00:00    4
Freq: H, dtype: int64
'''
# 三分鐘重取樣,計算均值
data.resample('3H').mean()
'''
2020-03-21 00:00:00     1
2020-03-21 03:00:00     4
2020-03-21 06:00:00     7
2020-03-21 09:00:00    10
2020-03-21 12:00:00    13
2020-03-21 15:00:00    16
2020-03-21 18:00:00    19
2020-03-21 21:00:00    22
Freq: 3H, dtype: int64
'''
# 五分鐘重取樣,求和
data.resample('5H').sum()
'''
2020-03-21 00:00:00    10
2020-03-21 05:00:00    35
2020-03-21 10:00:00    60
2020-03-21 15:00:00    85
2020-03-21 20:00:00    86
Freq: 5H, dtype: int64
'''
# 計算OHLC open,high,low,close
data.resample('5H').ohlc()
'''
                     open  high  low  close
2020-03-21 00:00:00     0     4    0      4
2020-03-21 05:00:00     5     9    5      9
2020-03-21 10:00:00    10    14   10     14
2020-03-21 15:00:00    15    19   15     19
2020-03-21 20:00:00    20    23   20     23
'''
# 將日期替換為第二天
data.index = data.index + pd.Timedelta('1D')
# 檢視前五條資料
data[:5]
'''
2020-03-22 00:00:00    0
2020-03-22 01:00:00    1
2020-03-22 02:00:00    2
2020-03-22 03:00:00    3
2020-03-22 04:00:00    4
Freq: H, dtype: int64
'''
# 檢視指定日期是星期幾
# pd.Timestamp('20200321').weekday_name
# 'Saturday'

# 檢視指定日期的年份是否是閏年
pd.Timestamp('20200301').is_leap_year
# True

# 檢視指定日期所在的季度和月份
day = pd.Timestamp('20200321')
# Timestamp('2020-03-21 00:00:00')

# 檢視日期的季度
day.quarter
# 1

# 檢視日期所在的月份
day.month
# 3

# 轉換為 python 的日期時間物件
day.to_pydatetime()
# datetime.datetime(2020, 3, 21, 0, 0)

# DateFrame 的建立,包含部分:index , column , values
import numpy as np
import pandas as pd

# 建立一個 DataFrame 物件
dataframe = pd.DataFrame(np.random.randint(1,20,(5,3)),
                         index = range(5),
                         columns = ['A','B','C'])
'''
    A   B   C
0  17   9  19
1  14   5   8
2   7  18  13
3  13  16   2
4  18   6   5
'''
# 索引為時間序列
dataframe2 = pd.DataFrame(np.random.randint(5,15,(9,3)),
                          index = pd.date_range(start = '202003211126',
                                                end = '202003212000',
                                                freq = 'H'),
                          columns = ['Pandas','爬蟲','比賽'])
'''
                     Pandas  爬蟲  比賽
2020-03-21 11:26:00       8  10   8
2020-03-21 12:26:00       9  14   9
2020-03-21 13:26:00       9   5  13
2020-03-21 14:26:00       9   7   7
2020-03-21 15:26:00      11  10  14
2020-03-21 16:26:00      12   7  10
2020-03-21 17:26:00      11  11  13
2020-03-21 18:26:00       8  13   8
2020-03-21 19:26:00       7   7  13
'''
# 使用字典進行建立
dataframe3 = pd.DataFrame({'語文':[87,79,67,92],
                           '數學':[93,89,80,77],
                           '英語':[88,95,76,77]},
                          index = ['張三','李四','王五','趙六'])
'''
    語文  數學  英語
張三  87  93  88
李四  79  89  95
王五  67  80  76
趙六  92  77  77
'''
# 建立時自動擴充
dataframe4 = pd.DataFrame({'A':range(5,10),'B':3})
'''
   A  B
0  5  3
1  6  3
2  7  3
3  8  3
4  9  3
'''

# C:\Users\lenovo\Desktop\總結\Python
# 讀取 Excel 檔案並進行篩選

import pandas as pd

# 設定列對齊
pd.set_option("display.unicode.ambiguous_as_wide",True)
pd.set_option("display.unicode.east_asian_width",True)

# 讀取工號姓名時段交易額,使用預設索引
dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx',
                          usecols = ['工號','姓名','時段','交易額'])

# 列印前十行資料
dataframe[:10]
'''
   工號  姓名         時段  交易額
0  1001  張三   9:00-14:00    2000
1  1002  李四  14:00-21:00    1800
2  1003  王五   9:00-14:00     800
3  1004  趙六  14:00-21:00    1100
4  1005  周七   9:00-14:00     600
5  1006  錢八  14:00-21:00     700
6  1006  錢八   9:00-14:00     850
7  1001  張三  14:00-21:00     600
8  1001  張三   9:00-14:00    1300
9  1002  李四  14:00-21:00    1500
'''
# 跳過 1 2 4 行,以第一列姓名為索引
dataframe2 = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx',
                           skiprows = [1,2,4],
                           index_col = 1)
'''注:張三李四趙六的第一條資料跳過
      工號      日期         時段  交易額      櫃檯
姓名                                               
王五  1003  20190301   9:00-14:00     800      食品
周七  1005  20190301   9:00-14:00     600    日用品
錢八  1006  20190301  14:00-21:00     700    日用品
錢八  1006  20190301   9:00-14:00     850  蔬菜水果
張三  1001  20190302  14:00-21:00     600  蔬菜水果
'''

# 篩選符合特定條件的資料
# 讀取超市營業額資料
dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx')

# 檢視 5 到 10 的資料
dataframe[5:11]
'''
    工號  姓名      日期         時段  交易額      櫃檯
5   1006  錢八  20190301  14:00-21:00     700    日用品
6   1006  錢八  20190301   9:00-14:00     850  蔬菜水果
7   1001  張三  20190302  14:00-21:00     600  蔬菜水果
8   1001  張三  20190302   9:00-14:00    1300    化妝品
9   1002  李四  20190302  14:00-21:00    1500    化妝品
10  1003  王五  20190302   9:00-14:00    1000      食品
'''
# 檢視第六行的資料,左閉右開
dataframe.iloc[5]
'''
工號             1006
姓名             錢八
時段      14:00-21:00
交易額            700
Name: 5, dtype: object
'''
dataframe[:5]
'''
   工號  姓名         時段  交易額
0  1001  張三   9:00-14:00    2000
1  1002  李四  14:00-21:00    1800
2  1003  王五   9:00-14:00     800
3  1004  趙六  14:00-21:00    1100
4  1005  周七   9:00-14:00     600
'''
# 檢視第 1 3 4 行的資料
dataframe.iloc[[0,2,3],:]
'''
   工號  姓名         時段  交易額
0  1001  張三   9:00-14:00    2000
2  1003  王五   9:00-14:00     800
3  1004  趙六  14:00-21:00    1100
'''
# 檢視第 1 3 4 行的第 1 2 列
dataframe.iloc[[0,2,3],[0,1]]
'''
   工號  姓名
0  1001  張三
2  1003  王五
3  1004  趙六
'''
# 檢視前五行指定,姓名、時段和交易額的資料
dataframe[['姓名','時段','交易額']][:5]
'''
   姓名         時段  交易額
0  張三   9:00-14:00    2000
1  李四  14:00-21:00    1800
2  王五   9:00-14:00     800
3  趙六  14:00-21:00    1100
4  周七   9:00-14:00     600
'''
dataframe[:5][['姓名','時段','交易額']]
'''
   姓名         時段  交易額
0  張三   9:00-14:00    2000
1  李四  14:00-21:00    1800
2  王五   9:00-14:00     800
3  趙六  14:00-21:00    1100
4  周七   9:00-14:00     600
'''
# 檢視第 2 4 5 行 姓名,交易額 資料 loc 函式,包含結尾
dataframe.loc[[1,3,4],['姓名','交易額']]
'''
   姓名  交易額
1  李四    1800
3  趙六    1100
4  周七     600
'''
# 檢視第四行的姓名資料
dataframe.at[3,'姓名']
# '趙六'

# 檢視交易額大於 1700 的資料
dataframe[dataframe['交易額'] > 1700]
'''
   工號  姓名         時段  交易額
0  1001  張三   9:00-14:00    2000
1  1002  李四  14:00-21:00    1800
'''
# 檢視交易額總和
dataframe.sum()
'''
工號                                                  17055
姓名      張三李四王五趙六週七錢八錢八張三張三李四王五趙六週七錢八李四王五張三...
時段      9:00-14:0014:00-21:009:00-14:0014:00-21:009:00...
交易額                                                17410
dtype: object
'''
# 某一時段的交易總和
dataframe[dataframe['時段'] == '14:00-21:00']['交易額'].sum()
# 8300

# 檢視張三在下午14:00之後的交易情況
dataframe[(dataframe.姓名 == '張三') & (dataframe.時段 == '14:00-21:00')][:10]
'''
   工號  姓名         時段  交易額
7  1001  張三  14:00-21:00     600
'''
# 檢視日用品的銷售總額
# dataframe[dataframe['櫃檯'] == '日用品']['交易額'].sum()

# 檢視張三總共的交易額
dataframe[dataframe['姓名'].isin(['張三'])]['交易額'].sum()
# 5200

# 檢視交易額在 1500~3000 之間的記錄
dataframe[dataframe['交易額'].between(1500,3000)]
'''
   工號  姓名         時段  交易額
0  1001  張三   9:00-14:00    2000
1  1002  李四  14:00-21:00    1800
9  1002  李四  14:00-21:00    1500
'''


# 檢視資料特徵和統計資訊
import pandas as pd
# 讀取檔案
dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx')

# 檢視所有的交易額資訊
dataframe['交易額'].describe()
'''
count      17.000000
mean     1024.117647
std       428.019550
min       580.000000
25%       700.000000
50%       850.000000
75%      1300.000000
max      2000.000000
Name: 交易額, dtype: float64
'''
# 檢視四分位數
dataframe['交易額'].quantile([0,0.25,0.5,0.75,1.0])
'''
0.00     580.0
0.25     700.0
0.50     850.0
0.75    1300.0
1.00    2000.0
Name: 交易額, dtype: float64
'''
# 交易額中值
dataframe['交易額'].median()
# 850.0

# 交易額最小的三個資料
dataframe['交易額'].nsmallest(3)
'''
12    580
4     600
7     600
Name: 交易額, dtype: int64
'''
dataframe.nsmallest(3,'交易額')
'''
      工號  姓名        日期           時段  交易額    櫃檯
12  1005  周七  20190302   9:00-14:00  580   日用品
4   1005  周七  20190301   9:00-14:00  600   日用品
7   1001  張三  20190302  14:00-21:00  600  蔬菜水果
'''
# 交易額最大的兩個資料
dataframe['交易額'].nlargest(2)
'''
0    2000
1    1800
Name: 交易額, dtype: int64
'''
dataframe.nlargest(2,'交易額')
'''
     工號  姓名        日期           時段   交易額   櫃檯
0  1001  張三  20190301   9:00-14:00  2000  化妝品
1  1002  李四  20190301  14:00-21:00  1800  化妝品
'''
# 檢視最後一個日期
dataframe['日期'].max()
# 20190303

# 檢視最小的工號
dataframe['工號'].min()
# 1001

# 第一個最小交易額的行下標
index = dataframe['交易額'].idxmin()
# 0

# 第一個最小交易額
dataframe.loc[index,'交易額']
# 580

# 最大交易額的行下標
index = dataframe['交易額'].idxmax()
dataframe.loc[index,'交易額']
# 2000


import pandas as pd

# 設定列對齊
pd.set_option("display.unicode.ambiguous_as_wide",True)
pd.set_option("display.unicode.east_asian_width",True)

# 讀取工號姓名時段交易額,使用預設索引
dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx',
                          usecols = ['工號','姓名','時段','交易額','櫃檯'])
dataframe[:5]
'''
   工號  姓名         時段  交易額    櫃檯
0  1001  張三   9:00-14:00    2000  化妝品
1  1002  李四  14:00-21:00    1800  化妝品
2  1003  王五   9:00-14:00     800    食品
3  1004  趙六  14:00-21:00    1100    食品
4  1005  周七   9:00-14:00     600  日用品
'''
# 按照交易額和工號降序排序,檢視五條資料
dataframe.sort_values(by = ['交易額','工號'],ascending = False)[:5]
'''
    工號  姓名         時段  交易額    櫃檯
0   1001  張三   9:00-14:00    2000  化妝品
1   1002  李四  14:00-21:00    1800  化妝品
9   1002  李四  14:00-21:00    1500  化妝品
8   1001  張三   9:00-14:00    1300  化妝品
16  1001  張三   9:00-14:00    1300  化妝品
'''
# 按照交易額和工號升序排序,檢視五條資料
dataframe.sort_values(by = ['交易額','工號'])[:5]
'''
    工號  姓名         時段  交易額      櫃檯
12  1005  周七   9:00-14:00     580    日用品
7   1001  張三  14:00-21:00     600  蔬菜水果
4   1005  周七   9:00-14:00     600    日用品
14  1002  李四   9:00-14:00     680  蔬菜水果
5   1006  錢八  14:00-21:00     700    日用品
'''
# 按照交易額降序和工號升序排序,檢視五條資料
dataframe.sort_values(by = ['交易額','工號'],ascending = [False,True])[:5]
'''
    工號  姓名         時段  交易額    櫃檯
0   1001  張三   9:00-14:00    2000  化妝品
1   1002  李四  14:00-21:00    1800  化妝品
9   1002  李四  14:00-21:00    1500  化妝品
8   1001  張三   9:00-14:00    1300  化妝品
16  1001  張三   9:00-14:00    1300  化妝品
'''
# 按工號升序排序
dataframe.sort_values(by = ['工號'])[:5]
'''
    工號  姓名         時段  交易額      櫃檯
0   1001  張三   9:00-14:00    2000    化妝品
7   1001  張三  14:00-21:00     600  蔬菜水果
8   1001  張三   9:00-14:00    1300    化妝品
16  1001  張三   9:00-14:00    1300    化妝品
1   1002  李四  14:00-21:00    1800    化妝品
'''
dataframe.sort_values(by = ['工號'],na_position = 'last')[:5]
'''
    工號  姓名         時段  交易額      櫃檯
0   1001  張三   9:00-14:00    2000    化妝品
7   1001  張三  14:00-21:00     600  蔬菜水果
8   1001  張三   9:00-14:00    1300    化妝品
16  1001  張三   9:00-14:00    1300    化妝品
1   1002  李四  14:00-21:00    1800    化妝品
'''
# 按列名升序排序
dataframe.sort_index(axis = 1)[:5]
'''
    交易額  姓名  工號         時段      櫃檯
0     2000  張三  1001   9:00-14:00    化妝品
1     1800  李四  1002  14:00-21:00    化妝品
2      800  王五  1003   9:00-14:00      食品
3     1100  趙六  1004  14:00-21:00      食品
4      600  周七  1005   9:00-14:00    日用品
'''
dataframe.sort_index(axis = 1,ascending = True)[:5]
'''
   交易額  姓名  工號         時段      櫃檯
0     2000  張三  1001   9:00-14:00    化妝品
1     1800  李四  1002  14:00-21:00    化妝品
2      800  王五  1003   9:00-14:00      食品
3     1100  趙六  1004  14:00-21:00      食品
4      600  周七  1005   9:00-14:00    日用品
'''

# 分組與聚合
import pandas as pd
import numpy as np

# 設定列對齊
pd.set_option("display.unicode.ambiguous_as_wide",True)
pd.set_option("display.unicode.east_asian_width",True)

# 讀取工號姓名時段交易額,使用預設索引
dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx',
                          usecols = ['工號','姓名','時段','交易額','櫃檯'])

# 對 5 的餘數進行分組
dataframe.groupby(by = lambda num:num % 5)['交易額'].sum()
'''
0    4530
1    5000
2    1980
3    3120
4    2780
Name: 交易額, dtype: int64
'''
# 檢視索引為 7 15 的交易額
dataframe.groupby(by = {7:'索引為7的行',15:'索引為15的行'})['交易額'].sum()
'''
索引為15的行    830
索引為7的行     600
Name: 交易額, dtype: int64
'''
# 檢視不同時段的交易總額
dataframe.groupby(by = '時段')['交易額'].sum()
'''
時段
14:00-21:00    8300
9:00-14:00     9110
Name: 交易額, dtype: int64
'''
# 各櫃檯的銷售總額
dataframe.groupby(by = '櫃檯')['交易額'].sum()
'''
櫃檯
化妝品      7900
日用品      2600
蔬菜水果    2960
食品        3950
Name: 交易額, dtype: int64
'''
# 檢視每個人在每個時段購買的次數
count = dataframe.groupby(by = '姓名')['時段'].count()
'''
姓名
周七    2
張三    4
李四    3
王五    3
趙六    2
錢八    3
Name: 時段, dtype: int64
'''
#
count.name = '交易人和次數'
'''

'''
# 每個人的交易額平均值並排序
dataframe.groupby(by = '姓名')['交易額'].mean().round(2).sort_values()
'''
姓名
周七     590.00
錢八     756.67
王五     876.67
趙六    1075.00
張三    1300.00
李四    1326.67
Name: 交易額, dtype: float64
'''
# 每個人的交易額
dataframe.groupby(by = '姓名').sum()['交易額'].apply(int)
'''
姓名
周七    1180
張三    5200
李四    3980
王五    2630
趙六    2150
錢八    2270
Name: 交易額, dtype: int64
'''
# 每一個員工交易額的中值
data = dataframe.groupby(by = '姓名').median()
'''
      工號  交易額
姓名              
周七  1005     590
張三  1001    1300
李四  1002    1500
王五  1003     830
趙六  1004    1075
錢八  1006     720
'''
data['交易額']
'''
姓名
周七     590
張三    1300
李四    1500
王五     830
趙六    1075
錢八     720
Name: 交易額, dtype: int64
'''
# 檢視交易額對應的排名
data['排名'] = data['交易額'].rank(ascending = False)
data[['交易額','排名']]
'''
      交易額  排名
姓名              
周七     590   6.0
張三    1300   2.0
李四    1500   1.0
王五     830   4.0
趙六    1075   3.0
錢八     720   5.0
'''
# 每個人不同時段的交易額
dataframe.groupby(by = ['姓名','時段'])['交易額'].sum()
'''
姓名  時段       
周七  9:00-14:00     1180
張三  14:00-21:00     600
      9:00-14:00     4600
李四  14:00-21:00    3300
      9:00-14:00      680
王五  14:00-21:00     830
      9:00-14:00     1800
趙六  14:00-21:00    2150
錢八  14:00-21:00    1420
      9:00-14:00      850
Name: 交易額, dtype: int64
'''
# 設定各時段累計
dataframe.groupby(by = ['姓名'])['時段','交易額'].aggregate({'交易額':np.sum,'時段':lambda x:'各時段累計'})
'''
      交易額        時段
姓名                    
周七    1180  各時段累計
張三    5200  各時段累計
李四    3980  各時段累計
王五    2630  各時段累計
趙六    2150  各時段累計
錢八    2270  各時段累計
'''
# 對指定列進行聚合,檢視最大,最小,和,平均值,中值
dataframe.groupby(by = '姓名').agg(['max','min','sum','mean','median'])
'''
      工號                          交易額                                
       max   min   sum  mean median    max   min   sum         mean median
姓名                                                                      
周七  1005  1005  2010  1005   1005    600   580  1180   590.000000    590
張三  1001  1001  4004  1001   1001   2000   600  5200  1300.000000   1300
李四  1002  1002  3006  1002   1002   1800   680  3980  1326.666667   1500
王五  1003  1003  3009  1003   1003   1000   800  2630   876.666667    830
趙六  1004  1004  2008  1004   1004   1100  1050  2150  1075.000000   1075
錢八  1006  1006  3018  1006   1006    850   700  2270   756.666667    720
'''
# 檢視部分聚合後的結果
dataframe.groupby(by = '姓名').agg(['max','min','sum','mean','median'])['交易額']
'''
       max   min   sum         mean  median
姓名                                       
周七   600   580  1180   590.000000     590
張三  2000   600  5200  1300.000000    1300
李四  1800   680  3980  1326.666667    1500
王五  1000   800  2630   876.666667     830
趙六  1100  1050  2150  1075.000000    1075
錢八   850   700  2270   756.666667     720
'''


# 處理異常值缺失值重複值資料差分
import pandas as pd
import numpy as np
import copy

# 設定列對齊
pd.set_option("display.unicode.ambiguous_as_wide",True)
pd.set_option("display.unicode.east_asian_width",True)

# 異常值

# 讀取工號姓名時段交易額,使用預設索引
dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx')

# 檢視交易額低於 2000 的三條資料
# dataframe[dataframe.交易額 < 2000]
dataframe[dataframe.交易額 < 2000][:3]
'''
   工號  姓名      日期         時段  交易額    櫃檯
1  1002  李四  20190301  14:00-21:00    1800  化妝品
2  1003  王五  20190301   9:00-14:00     800    食品
3  1004  趙六  20190301  14:00-21:00    1100    食品
'''
# 檢視上浮了 50% 之後依舊低於 1500 的交易額,檢視 4 條資料
dataframe.loc[dataframe.交易額 < 1500,'交易額'] = dataframe[dataframe.交易額 < 1500]['交易額'].map(lambda num:num*1.5)
dataframe[dataframe.交易額 < 1500][:4]
'''
    工號  姓名      日期         時段  交易額      櫃檯
2   1003  王五  20190301   9:00-14:00  1200.0      食品
4   1005  周七  20190301   9:00-14:00   900.0    日用品
5   1006  錢八  20190301  14:00-21:00  1050.0    日用品
6   1006  錢八  20190301   9:00-14:00  1275.0  蔬菜水果
'''
# 檢視交易額大於 2500 的資料
dataframe[dataframe.交易額 > 2500]
'''
Empty DataFrame
Columns: [工號, 姓名, 日期, 時段, 交易額, 櫃檯]
Index: []
'''
# 檢視交易額低於 900 或 高於 1800 的資料
dataframe[(dataframe.交易額 < 900)|(dataframe.交易額 > 1800)]
'''
    工號  姓名      日期        時段  交易額    櫃檯
0   1001  張三  20190301  9:00-14:00  2000.0  化妝品
8   1001  張三  20190302  9:00-14:00  1950.0  化妝品
12  1005  周七  20190302  9:00-14:00   870.0  日用品
16  1001  張三  20190303  9:00-14:00  1950.0  化妝品
'''
#  將所有低於 200 的交易額都替換成 200 處理異常值
dataframe.loc[dataframe.交易額 < 200,'交易額'] = 200

# 檢視低於 1500 的交易額個數
dataframe.loc[dataframe.交易額 < 1500,'交易額'].count()
# 9

# 將大於 3000 元的都替換為 3000 元
dataframe.loc[dataframe.交易額 > 3000,'交易額'] = 3000

# 缺失值

# 檢視有多少行資料
len(dataframe)
# 17

# 丟棄缺失值之後的行數
len(dataframe.dropna())
# 17

# 包含缺失值的行
dataframe[dataframe['交易額'].isnull()]
'''
Empty DataFrame
Columns: [工號, 姓名, 日期, 時段, 交易額, 櫃檯]
Index: []
'''
# 使用固定值替換缺失值
# dff = copy.deepcopy(dataframe)
# dff.loc[dff.交易額.isnull(),'交易額'] = 999
# 將缺失值設定為 999,包含結尾
# dff.iloc[[1,4,17],:]

# 使用交易額的均值替換缺失值
# dff = copy.deepcopy(dataframe)
# for i in dff[dff.交易額.isnull()].index:
#     dff.loc[i,'交易額'] = round(dff.loc[dff.姓名 == dff.loc[i,'姓名'],'交易額'].mean())
# dff.iloc[[1,4,17],:]

# 使用整體均值的 80% 填充缺失值
# dataframe.fillna({'交易額':round(dataframe['交易額'].mean() * 0.8)},inplace = True)
# dataframe.iloc[[1,4,16],:]


# 重複值
dataframe[dataframe.duplicated()]
'''
Empty DataFrame
Columns: [工號, 姓名, 日期, 時段, 交易額, 櫃檯]
Index: []
'''
# dff = dataframe[['工號','姓名','日期','交易額']]
# dff = dff[dff.duplicated()]
# for row in dff.values:
#     df[(df.工號 == row[0]) & (df.日期 == row[2]) &(df.交易額 == row[3])]


# 丟棄重複行
dataframe = dataframe.drop_duplicates()

# 檢視是否有錄入錯誤的工號和姓名
dff = dataframe[['工號','姓名']]
dff.drop_duplicates()
'''
   工號  姓名
0  1001  張三
1  1002  李四
2  1003  王五
3  1004  趙六
4  1005  周七
5  1006  錢八
'''

# 資料差分
# 檢視員工業績波動情況(每一天和昨天的資料作比較)
dff = dataframe.groupby(by = '日期').sum()['交易額'].diff()
'''
日期
20190301       NaN
20190302    1765.0
20190303   -9690.0
Name: 交易額, dtype: float64
'''
# [:5] dataframe.head()
dff.map(lambda num:'%.2f'%(num))[:5]
'''
日期
20190301         nan
20190302     1765.00
20190303    -9690.00
Name: 交易額, dtype: object
'''
# 檢視張三的波動情況
dataframe[dataframe.姓名 == '張三'].groupby(by = '日期').sum()['交易額'].diff()[:5]
'''
日期
20190301      NaN
20190302    850.0
20190303   -900.0
Name: 交易額, dtype: float64
'''


# 使用透視表與交叉表檢視業績彙總資料
import pandas as pd
import numpy as np
import copy

# 設定列對齊
pd.set_option("display.unicode.ambiguous_as_wide",True)
pd.set_option("display.unicode.east_asian_width",True)

dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx')
# 對姓名和日期進行分組,並進行求和
dff = dataframe.groupby(by = ['姓名','日期'],as_index = False).sum()
'''
    姓名      日期  工號  交易額
0   周七  20190301  1005     600
1   周七  20190302  1005     580
2   張三  20190301  1001    2000
3   張三  20190302  2002    1900
4   張三  20190303  1001    1300
5   李四  20190301  1002    1800
6   李四  20190302  2004    2180
7   王五  20190301  1003     800
8   王五  20190302  2006    1830
9   趙六  20190301  1004    1100
10  趙六  20190302  1004    1050
11  錢八  20190301  2012    1550
12  錢八  20190302  1006     720
'''
# 將 dff 的索引,列 設定成透視表形式
dff = dff.pivot(index = '姓名',columns = '日期',values = '交易額')
'''
日期  20190301  20190302  20190303
姓名                              
周七     600.0     580.0       NaN
張三    2000.0    1900.0    1300.0
李四    1800.0    2180.0       NaN
王五     800.0    1830.0       NaN
趙六    1100.0    1050.0       NaN
錢八    1550.0     720.0       NaN
'''
# 檢視前一天的資料
dff.iloc[:,:1]
'''
日期  20190301
姓名          
周七     600.0
張三    2000.0
李四    1800.0
王五     800.0
趙六    1100.0
錢八    1550.0
'''
# 交易總額小於 4000 的人的前三天業績
dff[dff.sum(axis = 1) < 4000].iloc[:,:3]
'''
日期  20190301  20190302  20190303
姓名                              
周七     600.0     580.0       NaN
李四    1800.0    2180.0       NaN
王五     800.0    1830.0       NaN
趙六    1100.0    1050.0       NaN
錢八    1550.0     720.0       NaN
'''
# 工資總額大於 2900 元的員工的姓名
dff[dff.sum(axis = 1) > 2900].index.values
# array(['張三', '李四'], dtype=object)

# 顯示前兩天每一天的交易總額以及每個人的交易金額
dataframe.pivot_table(values = '交易額',index = '姓名',columns = '日期',aggfunc = 'sum',margins = True).iloc[:,:2]
'''
日期  20190301  20190302
姓名                    
周七     600.0     580.0
張三    2000.0    1900.0
李四    1800.0    2180.0
王五     800.0    1830.0
趙六    1100.0    1050.0
錢八    1550.0     720.0
All     7850.0    8260.0
'''
# 顯示每個人在每個櫃檯的交易總額
dff = dataframe.groupby(by = ['姓名','櫃檯'],as_index = False).sum()
dff.pivot(index = '姓名',columns = '櫃檯',values = '交易額')
'''
櫃檯  化妝品  日用品  蔬菜水果    食品
姓名                                  
周七     NaN  1180.0       NaN     NaN
張三  4600.0     NaN     600.0     NaN
李四  3300.0     NaN     680.0     NaN
王五     NaN     NaN     830.0  1800.0
趙六     NaN     NaN       NaN  2150.0
錢八     NaN  1420.0     850.0     NaN
'''
# 檢視每人每天的上班次數
dataframe.pivot_table(values = '交易額',index = '姓名',columns = '日期',aggfunc = 'count',margins = True).iloc[:,:1]
'''
日期  20190301
姓名          
周七       1.0
張三       1.0
李四       1.0
王五       1.0
趙六       1.0
錢八       2.0
All        7.0
'''
# 檢視每個人每天購買的次數
dataframe.pivot_table(values = '交易額',index = '姓名',columns = '日期',aggfunc = 'count',margins = True)
'''
日期  20190301  20190302  20190303  All
姓名                                   
周七       1.0       1.0       NaN    2
張三       1.0       2.0       1.0    4
李四       1.0       2.0       NaN    3
王五       1.0       2.0       NaN    3
趙六       1.0       1.0       NaN    2
錢八       2.0       1.0       NaN    3
All        7.0       9.0       1.0   17
'''
# 交叉表
# 每個人每天上過幾次班
pd.crosstab(dataframe.姓名,dataframe.日期,margins = True).iloc[:,:2]
'''
日期  20190301  20190302
姓名                    
周七         1         1
張三         1         2
李四         1         2
王五         1         2
趙六         1         1
錢八         2         1
All          7         9
'''
# 每個人每天去過幾次櫃檯
pd.crosstab(dataframe.姓名,dataframe.櫃檯)
'''
櫃檯  化妝品  日用品  蔬菜水果  食品
姓名                                
周七       0       2         0     0
張三       3       0         1     0
李四       2       0         1     0
王五       0       0         1     2
趙六       0       0         0     2
錢八       0       2         1     0
'''
# 將每一個人在每一個櫃檯的交易總額顯示出來
pd.crosstab(dataframe.姓名,dataframe.櫃檯,dataframe.交易額,aggfunc='sum')
'''
櫃檯  化妝品  日用品  蔬菜水果    食品
姓名                                  
周七     NaN  1180.0       NaN     NaN
張三  4600.0     NaN     600.0     NaN
李四  3300.0     NaN     680.0     NaN
王五     NaN     NaN     830.0  1800.0
趙六     NaN     NaN       NaN  2150.0
錢八     NaN  1420.0     850.0     NaN
'''
# 每個人在每個櫃檯交易額的平均值,金額/天數
pd.crosstab(dataframe.姓名,dataframe.櫃檯,dataframe.交易額,aggfunc = 'mean').apply(lambda  num:round(num,2) )
'''
櫃檯   化妝品  日用品  蔬菜水果    食品
姓名                                   
周七      NaN   590.0       NaN     NaN
張三  1533.33     NaN     600.0     NaN
李四  1650.00     NaN     680.0     NaN
王五      NaN     NaN     830.0   900.0
趙六      NaN     NaN       NaN  1075.0
錢八      NaN   710.0     850.0     NaN
'''


# 重取樣 多索引 標準差 協方差
import pandas as pd
import numpy as np
import copy

# 設定列對齊
pd.set_option("display.unicode.ambiguous_as_wide",True)
pd.set_option("display.unicode.east_asian_width",True)

data = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx')

# 將日期設定為 python 中的日期型別
data.日期 = pd.to_datetime(data.日期)
'''
   工號  姓名                          日期         時段  交易額    櫃檯
0  1001  張三 1970-01-01 00:00:00.020190301   9:00-14:00    2000  化妝品
1  1002  李四 1970-01-01 00:00:00.020190301  14:00-21:00    1800  化妝品
2  1003  王五 1970-01-01 00:00:00.020190301   9:00-14:00     800    食品
'''
# 每七天營業的總額
data.resample('7D',on = '日期').sum()['交易額']
'''
日期
1970-01-01    17410
Freq: 7D, Name: 交易額, dtype: int64
'''
# 每七天營業總額
data.resample('7D',on = '日期',label = 'right').sum()['交易額']
'''
日期
1970-01-08    17410
Freq: 7D, Name: 交易額, dtype: int64
'''
# 每七天營業額的平均值
func = lambda item:round(np.sum(item)/len(item),2)
data.resample('7D',on = '日期',label = 'right').apply(func)['交易額']
'''
日期
1970-01-08    1024.12
Freq: 7D, Name: 交易額, dtype: float64
'''
# 每七天營業額的平均值
func = lambda num:round(num,2)
data.resample('7D',on = '日期',label = 'right').mean().apply(func)['交易額']
# 1024.12

# 刪除工號這一列
data.drop('工號',axis = 1,inplace = True)
data[:2]
'''
   姓名                          日期         時段  交易額    櫃檯
0  張三 1970-01-01 00:00:00.020190301   9:00-14:00    2000  化妝品
1  李四 1970-01-01 00:00:00.020190301  14:00-21:00    1800  化妝品
'''
# 按照姓名和櫃檯進行分組彙總
data = data.groupby(by = ['姓名','櫃檯']).sum()[:3]
'''
               交易額
姓名 櫃檯            
周七 日用品      1180
張三 化妝品      4600
     蔬菜水果     600
'''
# 檢視張三的彙總資料
data.loc['張三',:]
'''
          交易額
櫃檯            
化妝品      4600
蔬菜水果     600
'''
# 檢視張三在蔬菜水果的交易資料
data.loc['張三','蔬菜水果']
'''
交易額    600
Name: (張三, 蔬菜水果), dtype: int64
'''
# 多索引
# 重新讀取,使用第二列和第六列作為索引,排在前面
data = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx',index_col = [1,5])
data[:5]
'''
             工號      日期         時段  交易額
姓名 櫃檯                                       
張三 化妝品  1001  20190301   9:00-14:00    2000
李四 化妝品  1002  20190301  14:00-21:00    1800
王五 食品    1003  20190301   9:00-14:00     800
趙六 食品    1004  20190301  14:00-21:00    1100
周七 日用品  1005  20190301   9:00-14:00     600
'''
# 丟棄工號列
data.drop('工號',axis = 1,inplace = True)
data[:5]
'''
             日期         時段  交易額
姓名 櫃檯                                 
張三 化妝品  20190301   9:00-14:00    2000
李四 化妝品  20190301  14:00-21:00    1800
王五 食品    20190301   9:00-14:00     800
趙六 食品    20190301  14:00-21:00    1100
周七 日用品  20190301   9:00-14:00     600
'''
# 按照櫃檯進行排序
dff = data.sort_index(level = '櫃檯',axis = 0)
dff[:5]
'''
             工號      日期         時段  交易額
姓名 櫃檯                                       
張三 化妝品  1001  20190301   9:00-14:00    2000
     化妝品  1001  20190302   9:00-14:00    1300
     化妝品  1001  20190303   9:00-14:00    1300
李四 化妝品  1002  20190301  14:00-21:00    1800
     化妝品  1002  20190302  14:00-21:00    1500
'''
# 按照姓名進行排序
dff = data.sort_index(level = '姓名',axis = 0)
dff[:5]
'''
             工號      日期        時段  交易額
姓名 櫃檯                                      
周七 日用品  1005  20190301  9:00-14:00     600
     日用品  1005  20190302  9:00-14:00     580
張三 化妝品  1001  20190301  9:00-14:00    2000
     化妝品  1001  20190302  9:00-14:00    1300
     化妝品  1001  20190303  9:00-14:00    1300
'''
# 按照櫃檯進行分組求和
dff = data.groupby(level = '櫃檯').sum()['交易額']
'''
櫃檯
化妝品      7900
日用品      2600
蔬菜水果    2960
食品        3950
Name: 交易額, dtype: int64
'''
#標準差
data = pd.DataFrame({'A':[3,3,3,3,3],'B':[1,2,3,4,5],
                     'C':[-5,-4,1,4,5],'D':[-45,15,63,40,50]
                     })
'''
   A  B  C   D
0  3  1 -5 -45
1  3  2 -4  15
2  3  3  1  63
3  3  4  4  40
4  3  5  5  50
'''
# 平均值
data.mean()
'''
A     3.0
B     3.0
C     0.2
D    24.6
dtype: float64
'''
# 標準差
data.std()
'''
A     0.000000
B     1.581139
C     4.549725
D    42.700117
dtype: float64
'''
# 標準差的平方
data.std()**2
'''
A       0.0
B       2.5
C      20.7
D    1823.3
dtype: float64
'''
# 協方差
data.cov()
'''
     A      B       C        D
A  0.0   0.00    0.00     0.00
B  0.0   2.50    7.00    53.75
C  0.0   7.00   20.70   153.35
D  0.0  53.75  153.35  1823.30
'''
# 指定索引為 姓名,日期,時段,櫃檯,交易額
data = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx',
                     usecols = ['姓名','日期','時段','櫃檯','交易額'])
# 刪除缺失值和重複值,inplace = True 直接丟棄
data.dropna(inplace = True)
data.drop_duplicates(inplace = True)

# 處理異常值
data.loc[data.交易額 < 200,'交易額'] = 200
data.loc[data.交易額 > 3000,'交易額'] = 3000

# 使用交叉表得到不同員工在不同櫃檯的交易額平均值
dff = pd.crosstab(data.姓名,data.櫃檯,data.交易額,aggfunc = 'mean')
dff[:5]
'''
櫃檯       化妝品  日用品  蔬菜水果    食品
姓名                                       
周七          NaN   590.0       NaN     NaN
張三  1533.333333     NaN     600.0     NaN
李四  1650.000000     NaN     680.0     NaN
王五          NaN     NaN     830.0   900.0
趙六          NaN     NaN       NaN  1075.0
'''
# 檢視資料的標準差
dff.std()
'''
櫃檯
化妝品       82.495791
日用品       84.852814
蔬菜水果    120.277457
食品        123.743687
dtype: float64
'''
dff.cov()
'''
櫃檯           化妝品  日用品      蔬菜水果     食品
櫃檯                                                
化妝品    6805.555556     NaN   4666.666667      NaN
日用品            NaN  7200.0           NaN      NaN
蔬菜水果  4666.666667     NaN  14466.666667      NaN
食品              NaN     NaN           NaN  15312.5
'''

import pandas as pd
import copy

# 設定列對齊
pd.set_option("display.unicode.ambiguous_as_wide",True)
pd.set_option("display.unicode.east_asian_width",True)

data = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx',usecols = ['日期','交易額'])

dff = copy.deepcopy(data)
# 檢視周幾
dff['日期'] = pd.to_datetime(data['日期']).dt.weekday_name
'''
       日期  交易額
0  Thursday    2000
1  Thursday    1800
2  Thursday     800
'''
# 按照周幾進行分組,檢視交易的平均值
dff = dff.groupby('日期').mean().apply(round)
dff.index.name = '周幾'
dff[:3]
'''
          交易額
周幾            
Thursday  1024.0
'''
# dff = copy.deepcopy(data)
# 使用正則規則檢視月份日期
# dff['日期'] = dff.日期.str.extract(r'(\d{4}-\d{2})')
# dff[:5]

# 按照日 進行分組檢視交易的平均值 -1 表示倒數第一個
# data.groupby(data.日期.str.__getitem__(-1)).mean().apply(round)

# 檢視日期尾數為 1 的資料
# data[data.日期.str.endswith('1')][:12]

# 檢視日期尾數為 12 的交易資料,slice 為切片 (-2) 表示倒數兩個
# data[data.日期.str.slice(-2) == '12']

# 檢視日期中月份或天數包含 2  的交易資料
# data[data.日期.str.slice(-5).str.contains('2')][1:9]

import pandas as pd
import numpy as np

# 讀取全部資料,使用預設索引
data = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx')

# 修改異常值
data.loc[data.交易額 > 3000,'交易額'] = 3000
data.loc[data.交易額 < 200,'交易額'] = 200

# 刪除重複值
data.drop_duplicates(inplace = True)

# 填充缺失值
data['交易額'].fillna(data['交易額'].mean(),inplace = True)

# 使用交叉表得到每人在各櫃檯交易額的平均值
data_group = pd.crosstab(data.姓名,data.櫃檯,data.交易額,aggfunc = 'mean').apply(round)
# 繪製柱狀圖
data_group.plot(kind = 'bar')
# <matplotlib.axes._subplots.AxesSubplot object at 0x000001D681607888>


#  資料的合併
data1 = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx')
data2 = pd.read_excel(r'C:\Users\lenovo\Desktop\總結\Python\超市營業額.xlsx',sheet_name = 'Sheet2')
df1 = data1[:3]
'''
     工號  姓名        日期           時段   交易額   櫃檯
0  1001  張三  20190301   9:00-14:00  2000  化妝品
1  1002  李四  20190301  14:00-21:00  1800  化妝品
2  1003  王五  20190301   9:00-14:00   800   食品
'''
df2 = data2[:4]
'''
     工號  姓名        日期           時段   交易額    櫃檯
0  1006  錢八  20190301   9:00-14:00   850  蔬菜水果
1  1001  張三  20190302  14:00-21:00   600  蔬菜水果
2  1001  張三  20190302   9:00-14:00  1300   化妝品
3  1002  李四  20190302  14:00-21:00  1500   化妝品
'''
# 使用 concat 連線兩個相同結構的 DataFrame 物件
df3 = pd.concat([df1,df2])
'''
     工號  姓名        日期           時段   交易額    櫃檯
0  1001  張三  20190301   9:00-14:00  2000   化妝品
1  1002  李四  20190301  14:00-21:00  1800   化妝品
2  1003  王五  20190301   9:00-14:00   800    食品
0  1006  錢八  20190301   9:00-14:00   850  蔬菜水果
1  1001  張三  20190302  14:00-21:00   600  蔬菜水果
2  1001  張三  20190302   9:00-14:00  1300   化妝品
3  1002  李四  20190302  14:00-21:00  1500   化妝品
'''
# 合併,忽略原來的索引 ignore_index
df4 = df3.append([df1,df2],ignore_index = True)
'''
      工號  姓名        日期           時段   交易額    櫃檯
0   1001  張三  20190301   9:00-14:00  2000   化妝品
1   1002  李四  20190301  14:00-21:00  1800   化妝品
2   1003  王五  20190301   9:00-14:00   800    食品
3   1006  錢八  20190301   9:00-14:00   850  蔬菜水果
4   1001  張三  20190302  14:00-21:00   600  蔬菜水果
5   1001  張三  20190302   9:00-14:00  1300   化妝品
6   1002  李四  20190302  14:00-21:00  1500   化妝品
7   1001  張三  20190301   9:00-14:00  2000   化妝品
8   1002  李四  20190301  14:00-21:00  1800   化妝品
9   1003  王五  20190301   9:00-14:00   800    食品
10  1006  錢八  20190301   9:00-14:00   850  蔬菜水果
11  1001  張三  20190302  14:00-21:00   600  蔬菜水果
12  1001  張三  20190302   9:00-14:00  1300   化妝品
13  1002  李四  20190302  14:00-21:00  1500   化妝品
'''
# 按照列進行拆分
df5 = df4.loc[:,['姓名','櫃檯','交易額']]
# 檢視前五條資料
df5[:5]
'''
   姓名    櫃檯   交易額
0  張三   化妝品  2000
1  李四   化妝品  1800
2  王五    食品   800
3  錢八  蔬菜水果   850
4  張三  蔬菜水果   600
'''

# 合併 merge 、 join
# 按照工號進行合併,隨機檢視 3 條資料
rows = np.random.randint(0,len(df5),3)
pd.merge(df4,df5).iloc[rows,:]
'''
      工號  姓名        日期           時段   交易額   櫃檯
7   1002  李四  20190301  14:00-21:00  1800  化妝品
4   1002  李四  20190301  14:00-21:00  1800  化妝品
10  1003  王五  20190301   9:00-14:00   800   食品
'''
# 按照工號進行合併,指定其他同名列的字尾
pd.merge(df1,df2,on = '工號',suffixes = ['_x','_y']).iloc[:,:]
'''
     工號 姓名_x      日期_x         時段_x  ...      日期_y         時段_y 交易額_y  櫃檯_y
0  1001   張三  20190301   9:00-14:00  ...  20190302  14:00-21:00   600  蔬菜水果
1  1001   張三  20190301   9:00-14:00  ...  20190302   9:00-14:00  1300   化妝品
2  1002   李四  20190301  14:00-21:00  ...  20190302  14:00-21:00  1500   化妝品
'''
# 兩個表都設定工號為索引 set_index
df2.set_index('工號').join(df3.set_index('工號'),lsuffix = '_x',rsuffix = '_y').iloc[:]
'''
     姓名_x      日期_x         時段_x  交易額_x  ...      日期_y         時段_y  交易額_y  櫃檯_y
工號                                       ...                                    
1001   張三  20190302  14:00-21:00    600  ...  20190301   9:00-14:00   2000   化妝品
1001   張三  20190302  14:00-21:00    600  ...  20190302  14:00-21:00    600  蔬菜水果
1001   張三  20190302  14:00-21:00    600  ...  20190302   9:00-14:00   1300   化妝品
1001   張三  20190302   9:00-14:00   1300  ...  20190301   9:00-14:00   2000   化妝品
1001   張三  20190302   9:00-14:00   1300  ...  20190302  14:00-21:00    600  蔬菜水果
1001   張三  20190302   9:00-14:00   1300  ...  20190302   9:00-14:00   1300   化妝品
1002   李四  20190302  14:00-21:00   1500  ...  20190301  14:00-21:00   1800   化妝品
1002   李四  20190302  14:00-21:00   1500  ...  20190302  14:00-21:00   1500   化妝品
1006   錢八  20190301   9:00-14:00    850  ...  20190301   9:00-14:00    850  蔬菜水果

'''

函式實現 多個數據求平均值
def average(*args):
    print(args)
    # (1, 2, 3)
    # (1, 2, 3)
    print(len(args))
    # 3
    # 3
    print(sum(args, 0.0) / len(args))

average(*[1, 2, 3])
# 2.0
average(1, 2, 3)
# 2.0

使用 * 對傳入的列表進行解包

對傳入的資料進行分類
def bifurcate(lst, filter):
    print(lst)
    # ['beep', 'boop', 'foo', 'bar']

    print(filter)
    # [True, True, False, True]
    # 列表名,不是 filter 函式

    print(enumerate(lst))
    # <enumerate object at 0x0000017EB10B9D00>

    print(list(enumerate(lst)))
    # [(0, 'beep'), (1, 'boop'), (2, 'foo'), (3, 'bar')]

    print([
    [x for i, x in enumerate(lst) if filter[i] == True],
    [x for i, x in enumerate(lst) if filter[i] == False]
    ])
    '''
    filter[i] 主要是對列舉型別前面的索引和傳入的 filter 列表進行判斷是否重複
    '''
bifurcate(['beep', 'boop', 'foo', 'bar'], [True, True, False, True])

進階 對傳入的資料進行分類
def bifurcate_by(lst, fn):
    print(lst)
    # ['beep', 'boop', 'foo', 'bar']

    print(fn('baby'))
    # True

    print(fn('abc'))
    # False

    print([
    [x for x in lst if fn(x)],
    [x for x in lst if not fn(x)]
    ])

bifurcate_by(
  ['beep', 'boop', 'foo', 'bar'], lambda x: x[0] == 'b'
)
# [['beep', 'boop', 'bar'], ['foo']]

二進位制字元長度
def byte_size(s):
    print(s)
    #