python coding(二) Pandas 、PIL、cv2

目录

Pandas

Series

DataFrame

基本操作

操作文件

实例

天气数据检测

OpenCv,PIL

模拟人脸登陆验证

pygame

音乐播放器


Pandas

一个分析结构化数据的工具集。Pandas 以 NumPy 为基础(实现数据存储和运算),提供了专门用于数据分析的类型、方法和函数,对数据分析和数据挖掘提供了很好的支持;同时 pandas 还可以跟数据可视化工具 matplotlib 很好的整合在一起,实现数据可视化。Pandas 核心的数据类型是Series(数据系列)、DataFrame(数据窗/数据框),分别用于处理一维和二维的数据.

Series

Pandas 库中的Series对象可以用来表示一维数据结构,但是多了索引和一些额外的功能。Series类型的内部结构包含了两个数组,其中一个用来保存数据,另一个用来保存数据的索引。

import pandas as pd
import numpy as np
#Pandas 核心的数据类型Series(数据系列,Series对象可以用来表示一维数据结构
#data参数表示数据,index参数表示数据的索引
ser1 = pd.Series(data=[1, 2, 3, 4], index=['东', '南', '西', '北'])
print(ser1)              #两列 索引和值
ser1 += 10               #标量运算,数据运算
print(ser1)
#字典的键就是数据的标签(索引),键对应的值就是数据
ser2 = pd.Series({'东': 1, '南': 2, '西': 3, '北': 4})
print(ser1 + ser2) #矢量运算
#Series对象也可以进行索引和切片操作
print(ser2['东'])
ser2[1:3] = 40, 50                   #切片操作
print(ser2[ser2 >= 5])               #过滤
#Series对象的属性与方法
print(ser2.dtype)                    # 数据类型           int64
print(ser2.hasnans)                  # 有没有空值         False
print(ser2.index)  # 索引  Index(['东', '南', '西', '北'], dtype='object')
print(ser2.values)                   # 值      [ 1 40 50  4]
print(ser2.is_monotonic_increasing)  # 是否单调递增        False
print(ser2.is_unique)                # 是否每个值都独一无二 True
print(ser2.count())                  # 计数               4
print(ser2.sum())                    # 求和               95
print(ser2.mean())                   # 求平均             23.75
print(ser2.median())                 # 找中位数           22.0
print(ser2.max())                    # 找最大             50
print(ser2.min())                    # 找最小             1
print(ser2.std())                    # 求标准差       24.904818810824544
print(ser2.var())                    # 求方差         620.25
print(ser2.describe())               #描述性统计信息
ser2['东']=4
print(ser2.value_counts())           #统计每个值重复的次数 4   2/ 40    1/  50  1
print(ser2.unique())                 #unique()方法获得由独一无二的值构成的数组
print(ser2.nunique())                #不重复值的数量
#Series对象的isna()和isnull()方法可以用于空值的判断,notna()和notnull()
#dropna()和fillna()方法分别用来删除空值和填充空值 fillna(value=10)  # 将空值填充为10
#Series对象的mask()和where()方法可以将满足或不满足条件的值进行替换
print(ser2.where(ser2 < 40, 10)) #数值大于40的替换为10
print(ser2.mask(ser2 < 40, 10))  #数值小于40 的替换为10
print(ser2)
print(ser2.duplicated())         #找出重复数据
print(ser2.drop_duplicates())    #去除重复数据
ser3 = pd.Series(['东', '南', np.nan, '北'])
print(ser3)
print(ser3.map({'东': '黄药师', '南': '段皇'}))
print(ser2.apply(np.square))          #数据平方
print(ser2.apply(lambda x, value: x - value, args=(4, ))) #数值-4
#sort_index()和sort_values()方法可以用于对索引和数据的排序
print(ser2.sort_values())  #数值大小排序
print(ser2.sort_index(ascending=True))
print(ser2.nlargest(2))  #top-N
print(ser2.nsmallest(2)) # 值最小的2个
import matplotlib.pyplot as plt
from pylab import *
# 通过plot方法的kind指定图表类型为柱状图
rcParams['font.sans-serif']=['SimHei']  #显示中文
ser2.plot(kind='bar')
plt.ylim(0, 60) # 定制纵轴的取值范围
# 定制横轴刻度(旋转到0度)
plt.xticks(rotation=0)
# 为柱子增加数据标签,索引作为横坐标,使用Series对象的数据作为纵坐标
for i in range(ser2.size):
    plt.text(i, ser2[i] + 0.5, ser2[i], ha='center')
plt.show()
# kind指定了图表类型为饼图 autopct会自动计算并显示百分比
# pctdistance用来控制百分比到圆心的距离
ser1.plot(kind='pie', autopct='%.1f%%', pctdistance=0.65)
plt.show()

DataFrame

DataFrame可以用来保存和处理‘多类型’的二维数据,DataFrame中每个列的数据类型不需要相同,DataFrame提供了极为丰富的属性和方法,实现对数据的重塑、清洗、预处理、透视、呈现等一系列操作。 

基本操作

#创建一个简单的DataFrame
#变量=pd.DataFrame(数据,[,columns=列标题列表,index=行标题列表]})
name =  ['John', 'Anna', 'Peter', 'Linda']
age = [28, 23, 34, 29]
colum=['年龄']
df = pd.DataFrame(data=age ,columns=colum, index=name)
print(df)
#字典创建
print('------------')
data = {
    'Name': ['John', 'Anna', 'Peter', 'Linda'],
    'Age': [28, 23, 34, 29],
    'City': ['New York', 'Paris', 'Berlin', 'London']
}
df = pd.DataFrame(data)
#df1=df.drop(0,axis=0) #默认行号从0开始
#df.index修改行标题列表, df.columns=[] 修改列标题
print(df.iloc[0]) # 通过位置选择行
print(df.loc[0])  # 通过标签选择行
print('------------')
df.index=['John', 'Anna', 'Peter', 'Linda']
print(df.head(2))  # 查看前2行
print(df.tail(2))  # 查看后2行
print(df.info())  # 查看 DataFrame 的基本信息
print(df['Name']) #选择一个列
print(df[['Name', 'Age']]) #选择多列
print(df[df['Age'] > 30]) # 通过条件过滤数据

# 对数据进行排序
print(df.sort_values(by='Age',ascending=False))
# 对列名进行重命名
df.rename(columns={'Name': 'PersonName'}, inplace=True)
print(df)
df1=df.drop('John') #删除
print(df1)
df['Salary'] = [7000, 8000, 9000,10000] #添加一列
print(df)

操作文件

读取csv: df = pd.read_csv('data/数据.csv', index_col='xx')

导出:df.to_csv('output.csv', index=False)  # 导出为 CSV 文件

读取exec:  df= pd.read_excel('data/数据.xlsx', sheet_name='xx', index_col='xx')

导出:df.to_excel('output.xlsx', index=False)  # 导出为 Excel 文件

实例

天气数据检测

基于pandas和tkinter编写北京历史天气数据,点击刷新可以显示天气指数

import tkinter as tk
import pandas as pd
url = 'https://tianqi.2345.com/wea_history/54511.htm'
dt=pd.read_html(url)
data=dt[0]

win=tk.Tk()
win.geometry("1100x470")
win.title('天气数据')
datav=tk.StringVar()
result1=tk.StringVar()
datalist=[]
datalistv={k: v for k, v in zip(data['日期'], data['天气'])}
for c1 in data['日期']:
    datalist.append(c1)
label1=tk.Label(win,text='日期',pady=6,fg='blue',font=('新细明体',22))
label1.pack()
fram1=tk.Frame(win)
fram1.pack()

def rbdate():   #单击按钮处理函数
    for s in datalistv:
        if s==datav.get():    #按钮得text
            result1.set(s+' 天气情况是:'+datalistv[s]) #显示文本
def cliRefsh():  #刷新处理
    global data,datalistv
    url = 'https://tianqi.2345.com/wea_history/54511.htm'
    dt=pd.read_html(url)
    data=dt[0]
    datalistv={k: v for k, v in zip(data['日期'], data['天气']+' 空气质量指数值 '+data['空气质量指数'])}
    rbtem.select()
    rbdate()
for i in range(0,3): #按钮排列
    for j in range(0,8):
        n=i*8+j
        if n<len(datalist):
            date1=datalist[n]
            rbtem=tk.Radiobutton(fram1,text=date1,variable=datav,value=date1,command=rbdate)
            rbtem.grid(row=i,column=j)
            if n==0:
                rbtem.select()
btnDown=tk.Button(win,text='更新',command=cliRefsh)
btnDown.pack(pady=6)
lblResult=tk.Label(win,textvariable=result1,fg='red',font=('新细明体',22))
lblResult.pack(pady=7)
rbdate()
win.mainloop()

OpenCv,PIL

模拟人脸登陆验证

功能-》打开摄像头-》预存人脸库;  登录验证使用直方图计算登录图像和预存图像得差距验证是否通过,直方图得误差计算受光照环境影响较大。

import cv2, os, math, operator
from PIL import Image
from functools import reduce

def makeFace(path,facename, msg, endstr):
    print(msg)  #显示提示信息
    cv2.namedWindow("frame")
    cv2.waitKey(0)
    cap = cv2.VideoCapture(0)  #打开摄像头
    while(cap.isOpened()):  #如果摄像头处于打开状态,则...
        ret, img = cap.read()  #读取图像
        if ret == True:  #读取成功
            cv2.imshow("frame", img)  #显示图像
            k = cv2.waitKey(100)  #每0.1秒读一次键盘
            if k == ord("s") or k == ord("S"):  #如果输入z
                if not os.path.exists(path):
                    os.makedirs(path)       #文件路径,如果没有不会自动创建文件夹
                cv2.imwrite(facename,img)   #把读取的img保存至facename文件
                image = cv2.imread(facename)  #读取刚刚保存的facename文件至image变量,作为下面人脸识别函数的参数
                faces = faceCascade.detectMultiScale(image, scaleFactor=1.1, minNeighbors=5, minSize=(30,30), flags = cv2.CASCADE_SCALE_IMAGE)
                (x, y, w, h) = (faces[0][0], faces[0][1], faces[0][2], faces[0][3])  #取出第一张人脸区域
                image1 = Image.open(facename).crop((x, y, x+w, y+h))        #抓取人脸区域的图像并存至image1变量
                image1 = image1.resize((200, 200))   #把取得的人脸区域的分辨率变为200x200
                image1.save(facename)                #把经过处理的人脸文件保存至facename文件
                break
    cap.release()  #关闭摄像头
    cv2.destroyAllWindows()   #关闭窗口
    print(endstr)    
    return
faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')  #创建识别对象
path='data'
recogname = "data\\recogface.jpg"  #预存的人脸文件
loginname = "data\\loginface.jpg"  #登录者的人脸文件
os.system("cls")  #清屏
if(os.path.exists(recogname)):  #如果预存的人脸文件已存在
    msg = "按任意键创建登录人脸文件。摄像头打开后按s键进行人脸图像采集"
    makeFace(path,loginname, msg, "")   #创建登录者人脸文件
    pic1 = Image.open(recogname)        #打开预存的人脸文件
    pic2 = Image.open(loginname)        #打开登录者人脸文件
    h1 = pic1.histogram()               #取预存片文件的直方图信息
    h2 = pic2.histogram()               #取登录者图片的直方图信息
    diff = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2, h1, h2)))/len(h1)) #计算两个图形差异度
    if(diff <= 100):  #若差度在100内,可通过验证
        print("通过验证,欢迎使用本系统! diff=%4.2f" % diff)
    else:
        print("人脸错误,无法使用本系统! diff=%4.2f" % diff)
else:  #如果预存的人脸文件不存在
    msg = "按任意键创建预存的人脸文件,摄像头打开后按s进行图像采集\n"
    endstr = "预存文件建立完成!"
    makeFace(path,recogname, msg, endstr)  #建立预存人脸文件

pygame

音乐播放器

def choose(): # 选曲
    global playsong
    msg.set("\n播放歌曲: " + choice.get())
    playsong=choice.get()   
def pausemp3(): #暂停
    mixer.music.pause() 
    msg.set("\n暂停播放 {}".format(playsong))    
def increase(): #加大音量
    global volume
    volume +=0.1
    if volume>=1:
        volume=1
    mixer.music.set_volume(volume)  
def decrease(): #调小音量
    global volume
    volume -=0.1
    if volume<=0.3:
        volume=0.3
    mixer.music.set_volume(volume)     
def playmp3(): #播放
    global status,playsong,preplaysong
    if playsong==preplaysong: #同一首歌曲
        if not mixer.music.get_busy():
            mixer.music.load(playsong)
            mixer.music.play(loops=-1) 
        else:
            mixer.music.unpause() 
        msg.set("\n正在播放:{}".format(playsong))
    else: # 更换歌曲
        msg.set("\n正在播放:{}".format(playsong))
        playNewmp3()
        preplaysong=playsong 
        
def playNewmp3(): #播放新曲
    global playsong
    mixer.music.stop()
    mixer.music.load(playsong)   
    mixer.music.play(loops=-1)  
    msg.set("\n正在播放:{}".format(playsong))
  
def stopmp3(): #停止播放
    mixer.music.stop()
    msg.set("\n停止播放") 
def exitmp3(): # 结束
    mixer.music.stop()
    win.destroy() 
### 主程序从这里开始 ###    
def chose():
    directory = askdirectory()
    os.chdir(directory)
    song_list = os.listdir()
    mp3files =[r for r in song_list if r.lower().endswith('.mp3') or r.lower().endswith('.wav') ]
    return mp3files
def make_radio(mp3files,flag):
    global playsong,preplaysong,choice,radio_buttons
    if flag:
        for radio in radio_buttons:
            radio.destroy()
    playsong=preplaysong = ""
    index = 0
    choice = tk.StringVar()
    for mp3 in mp3files:  #建立歌曲菜单按钮
        rbtem = tk.Radiobutton(frame1,text=mp3,variable=choice,value=mp3,command=choose)
        if(index==0):  #选择第1个按钮       
            rbtem.select()
            playsong=preplaysong=mp3
        rbtem.grid(row=index, column=0, sticky="w")
        index += 1
        radio_buttons.append(rbtem)
    
import tkinter as tk
from pygame import mixer
from tkinter.filedialog import askdirectory
import os
def chose_new(): # 重选文件
    mp3files=[]
    mp3files=chose() 
    make_radio(mp3files,True)
mixer.init()
win=tk.Tk()
win.geometry("640x380")
win.title("mp3格式音乐播放器")

labeltitle = tk.Label(win, text="\n音乐播放器", fg="red",font=("黑体",22))
labeltitle.pack()
 
frame1 = tk.Frame(win)  # 歌曲容器
frame1.pack()
mp3files =chose()
while len(mp3files)==0:
    tk.messagebox.showwarning("Error", "Selected folder is invalid. Please select a valid folder.")
    mp3files=chose()
    if mp3files is not None:
        pass

volume=0.6
radio_buttons = []
make_radio(mp3files,False)

    
msg = tk.StringVar()
msg.set("\n播放歌曲:")
label = tk.Label(win, textvariable=msg,fg="blue",font=("新细明体",10))
label.pack() 
labelsep = tk.Label(win, text="\n")
labelsep.pack()   
    
frame2 = tk.Frame(win)  # 按钮容器
frame2.pack()    
button1 = tk.Button(frame2, text="播放", width=8,command=playmp3)
button1.grid(row=0, column=0, padx=5, pady=5)
button2 = tk.Button(frame2, text="暂停", width=8,command=pausemp3)
button2.grid(row=0, column=1, padx=5, pady=5)
button3 = tk.Button(frame2, text="音量调大", width=8,command=increase)
button3.grid(row=0, column=2, padx=5, pady=5)
button4 = tk.Button(frame2, text="音量调小", width=8,command=decrease)
button4.grid(row=0, column=3, padx=5, pady=5)
button5 = tk.Button(frame2, text="停止", width=8,command=stopmp3)
button5.grid(row=0, column=4, padx=5, pady=5)
button6 = tk.Button(frame2, text="结束", width=8,command=exitmp3)
button6.grid(row=0, column=5, padx=6, pady=6)
button7 = tk.Button(frame2, text="重选文件", width=8,command=chose_new)
button7.grid(row=0, column=6, padx=7, pady=7)
win.protocol("WM_DELETE_WINDOW", exitmp3)
win.mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值