飲冰三年-人工智慧-Pandas-74-初始Pandas
一、什麼是Pandas
Pandas,python+data+analysis的組合縮寫,是python中基於numpy和matplotlib的第三方資料分析庫,與後兩者共同構成了python資料分析的基礎工具包,享有數分三劍客之名。
Pandas 的目標是成為 Python 資料分析實踐與實戰的必備高階工具,其長遠目標是成為最強大、最靈活、可以支援任何語言的開源資料分析工具。
- 高效能
- 易使用的資料結構
- 易使用的資料分析工具
python 社群已經廣泛接受了一些常用模組的命名慣例:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
也就是說,當你看到np.arange時,就應該想到它引用的是NumPy中的arange函式。這樣做的原因是:在Python軟體開發中,不建議直接引入類似NumPy這種大型庫的全部內容(from numpy import *)。
二、Pandas資料讀取
1、讀取txt、CSV等文字資料
1.1 按照逗號分割的txt文字檔案
df = pd.read_csv('C:\\Users\\ywx1106919\\Desktop\\ex1.txt', encoding='utf-8')
1.2 按照tab分割的csv檔案
df = pd.read_table('C:\\Users\\ywx1106919\\Desktop\\ex2.csv', encoding='utf-8')
1.3 常用方法總結:
函式 | 說明 |
read_csv | 從檔案、URL、檔案型物件中載入帶分隔符的資料。預設分隔符為逗號。 |
read_table | 從檔案、URL、檔案型物件中載入帶分隔符的資料。預設分隔符為製表符(“\t”)。 |
read_fwf | 讀取定寬列格式資料(也就是說,沒有分隔符) |
read_clipboard | 讀取剪貼簿中的資料,可以看做read_table的剪下板版。在將網頁轉換成表格時很有用。 |
1.4 拋磚引玉,後面有機會詳細介紹
- 我們可以通過sep引數修改預設分隔符。
- 我們可以通過header引數申明標題行。
- 我們可以通過names引數自定製列名。
- 我們可以通過index_col引數設定索引列。
2、讀取Excel中資料
ps:使用read_excel 需要安裝openpyxl包
pip install openpyxl
2.1 讀取Excel檔案
df = pd.read_excel('C:\\Users\\ywx1106919\\Desktop\\ex3.xlsx')
3、讀取資料庫中資料
3.1 讀取MySQL資料庫中資料
ps:使用mysql資料庫需要安裝mysqlclient、pymysql包
pip install pymysql
pip install mysqlclient
conn = pymysql.connect(host=MYSQL_HOST, port=MYSQL_PORT, db=MYSQL_NAME, user=MYSQL_USER, password=MYSQL_PASSWORD, ) mysql_page = pd.read_sql("SELECT id,subject_name FROM tb_course", con=conn)
3.2 彩蛋:舊版本獲取資料會有警告提示:
UserWarning: pandas only support SQLAlchemy connectable(engine/connection) ordatabase string URI or sqlite3 DBAPI2 connectionother DBAPI2 objects are not tested, please consider using SQLAlchemy warnings.warn(
新版本的pandas庫中con引數使用sqlalchemy庫建立的create_engine物件 。建立create_engine物件(格式類似於URL地址),
需要安裝 sqlalchemy
def get_data_from_db(): """ 新版本的pandas庫中con引數使用sqlalchemy庫建立的create_engine物件 建立create_engine物件(格式類似於URL地址): """ engine = create_engine('mysql+pymysql://%s:%s@%s:%s/%s?charset=utf8' % (MYSQL_USER, MYSQL_PASSWORD, MYSQL_HOST, MYSQL_PORT, MYSQL_NAME)) mysql_page = pd.read_sql("SELECT * FROM tb_score", engine) print(mysql_page)新版本使用demo
三、Pandas資料結構
要使用pandas,首先就得熟悉它的兩個主要資料結構:Series和DataFrame。雖然它們並不能解決所有問題,但它們為大多數應用提供了一種可靠的、易於使用的基礎。
Series
Series是類似於一維陣列的物件。它由一組資料(可以是不同資料型別)以及一組與之相關的額資料標籤(索引)組成。
1:一組資料即可產生最簡單的Series
import pandas as pd def series_01(): pd_s = pd.Series([4, 7, -5, 3]) print(pd_s) print(pd_s[3]) series_01()程式碼
0 4
1 7
2 -5
3 3
dtype: int64
3
輸出結果
取值方式:通過索引取值。python中的切片功能同樣適用。
展示形式:索引在左,值在右。
我們沒有為資料指定索引,於是會自動建立一個0至N-1的整數索引。你可以通過Series的index和values獲取其索引物件和陣列表示形式
2:一組資料+索引組成的Series
通常,我們希望所建立的Series帶有一個可以對各個資料點進行標記的索引。
def series_02(): # 建立一個可以對各個資料進行標記的索引 pd_s = pd.Series([4, 7, -5, 3], index=["d", "b", "a", "c"]) print(pd_s) print("------通過下標取值---------") print(pd_s[1:3]) print("------通過索引取值---------") print(pd_s[["a", "b", "c"]]) print("-------檢視索引--------") print(pd_s.index) print("-------檢視值--------") print(pd_s.values)View Code
d 4 b 7 a -5 c 3 dtype: int64 ------通過下標取值--------- b 7 a -5 dtype: int64 ------通過索引取值--------- a -5 b 7 c 3 dtype: int64 -------檢視索引-------- Index(['d', 'b', 'a', 'c'], dtype='object') -------檢視值-------- [ 4 7 -5 3]輸出結果
你可以通過索引的方式選取Series中的單個或一組值。上面展示了通過 pd_s[["a", "b", "c"]] 取一組值,可通過pd_s["a"]取單個值。
3:數學運算
常見的數學運算(如根據布林型陣列進行過濾、標量乘法、應用數學函式等)都會保留索引和值之間的連結。
def series_03(): pd_s = pd.Series([4, 7, -5, 3], index=["d", "b", "a", "c"]) print(pd_s) print("------布林型陣列過濾---------") print(pd_s[pd_s > 0]) print("------標量乘法---------") print(pd_s * 2) print("-------應用數學函式--------") # exp():返回e的冪次方,e是一個常數為2.71828。np.exp(1) 為自身,np.exp(2) 為平方 print(np.exp(pd_s))View Code
d 4 b 7 a -5 c 3 dtype: int64 ------布林型陣列過濾--------- d 4 b 7 c 3 dtype: int64 ------標量乘法--------- d 8 b 14 a -10 c 6 dtype: int64 -------應用數學函式-------- d 54.598150 b 1096.633158 a 0.006738 c 20.085537 dtype: float64輸出結果
4:Series可以看成一個定長的有序字典。
Series它本身是索引值到資料值的一個對映。
def series_04(): dict_data = {"張三": 20, "李四": 22, "王五": 23, "趙六": 20} pd_s = pd.Series(dict_data) # 字典直接轉 print(pd_s) print("------布林判斷是否存在---------") print("張三" in dict_data, "張三三" in dict_data) print("------檢視索引---------") print(pd_s.index) print("-------給索引通過賦值的方式就地修改--------") pd_s.index = ["zhangsan", "lisi", "wangwu", "zhaoliu"] print(pd_s)View Code
張三 20 李四 22 王五 23 趙六 20 dtype: int64 ------布林判斷是否存在--------- True False ------檢視索引--------- Index(['張三', '李四', '王五', '趙六'], dtype='object') -------給索引通過賦值的方式就地修改-------- zhangsan 20 lisi 22 wangwu 23 zhaoliu 20 dtype: int64輸出結果
DataFrame
DataFrame 是一個表格型的資料結構,它含有一組有序的列,每列可以是不同的值型別(數值、字串、布林值等),可對應資料庫中的欄位。
DataFrame 既有行索引又有列索引,它可以被看做由Series組成的字典。
1:根據多個字典序列建立dataframe
構建DataFrame的方法有很多最常用的一種是直接傳入一個由等長列表或者NumPy陣列組成的字典。
def data_frame_01(): data = { 'name': ['張三', '李四', '王五', '趙六'], 'year': [2020, 2021, 2022, 2023], 'pop': [3, 2, 1, 4], } frame = pd.DataFrame(data) print(frame) data_frame_01()View Code
""" name year pop 0 張三 2020 3 1 李四 2021 2 2 王五 2022 1 3 趙六 2023 4 """輸出結果
從資料結果可以看出,DataFrame會自動加上索引。同樣的,我們可以指定列的順序和自定義索引。
def data_frame_02(): data = { 'name': ['張三', '李四', '王五', '趙六'], 'year': [2020, 2021, 2022, 2023], 'pop': [3, 2, 1, 4], } frame = pd.DataFrame(data, columns=['pop', 'year', 'name', 'age'], index=['one', 'two', 'three', 'four']) print(frame)View Code
pop year name age one 3 2020 張三 NaN two 2 2021 李四 NaN three 1 2022 王五 NaN four 4 2023 趙六 NaN輸出結果
跟Series一樣如果傳入的列在資料中找不到,就會產生NA值。
2:從dataframe中查出Series
如果只查詢一行、一列返回的是series。
-
- 列篩選:通過類似字典標記的方式或屬性的方式 frame['pop']
- 行篩選:通過行號獲取行 frame.iloc[1]
- 行篩選:通過索引獲取行 frame.loc['one']
def data_frame_03(): # 如果只查詢一行、一列返回的是series。 # 列篩選:通過類似字典標記的方式或屬性的方式 frame['pop'] # 行篩選:通過行號獲取行 frame.iloc[1] # 行篩選:通過索引獲取行 frame.loc['one'] data = { 'name': ['張三', '李四', '王五', '趙六'], 'year': [2020, 2021, 2022, 2023], 'pop': [3, 2, 1, 4], } frame = pd.DataFrame(data, columns=['pop', 'year', 'name', 'age'], index=['one', 'two', 'three', 'four']) a_col = frame['pop'] print("-------------獲取某列----------") print(a_col) a_row_by_iloc = frame.iloc[1] print("-------------通過行號獲取行----------") print(a_row_by_iloc) a_row_by_loc = frame.loc['one'] print("-------------通過索引獲取行----------") print(a_row_by_loc)View Code
-------------獲取某列---------- one 3 two 2 three 1 four 4 Name: pop, dtype: int64 -------------通過索引獲取行---------- pop 2 year 2021 name 李四 age NaN Name: two, dtype: object -------------通過行號獲取行---------- pop 3 year 2020 name 張三 age NaN Name: one, dtype: object輸出結果
如果查詢多行,返回的仍是DataFrame。
-
- 列篩選:通過類似字典標記的方式或屬性的方式 frame[['pop'], ['year']]
- 行篩選:通過索引獲取行 frame.loc[['one', 'three']]
- 行篩選:通過行號獲取多行 fram.iloc[0:2]
def data_frame_03_n(): # 如果查詢多行,返回的仍是DataFrame。 # 列篩選:通過類似字典標記的方式或屬性的方式 frame[['pop'], ['year']] # 行篩選:通過索引獲取行 frame.loc[['one', 'three']] # 行篩選:通過行號獲取多行 fram.iloc[0:2] data = { 'name': ['張三', '李四', '王五', '趙六'], 'year': [2020, 2021, 2022, 2023], 'pop': [3, 2, 1, 4], } frame = pd.DataFrame(data, columns=['pop', 'year', 'name', 'age'], index=['one', 'two', 'three', 'four']) m_col = frame[['pop', 'year']] print("-------------獲取多列----------") print(m_col) m_row_by_iloc = frame.iloc[0:2] print("-------------通過行號獲取多行----------") print(m_row_by_iloc) m_row_by_loc = frame.loc[['one', 'three']] print("-------------通過索引獲取行----------") print(m_row_by_loc)View Code
-------------獲取多列---------- pop year one 3 2020 two 2 2021 three 1 2022 four 4 2023 -------------通過行號獲取多行---------- pop year name age one 3 2020 張三 NaN two 2 2021 李四 NaN -------------通過索引獲取行---------- pop year name age one 3 2020 張三 NaN three 1 2022 王五 NaN輸出結果
3:dataframe修改
一言以蔽之:獲取目標,賦值
def data_frame_03_m(): data = { 'name': ['張三', '李四', '王五', '趙六'], 'year': [2020, 2021, 2022, 2023], 'pop': [3, 2, 1, 4], } frame = pd.DataFrame(data, columns=['pop', 'year', 'name', 'age'], index=['one', 'two', 'three', 'four']) frame['age'] = 18 print("-------------獲取某列,然後統一賦一個值----------") print(frame) frame['age'] = np.arange(4, ) print("-------------獲取某列,然後賦一個(可遞迴)值----------") print(frame) val = pd.Series([17, 18], index=['one', 'three', ]) frame['age'] = val print("-------------定義Series【值和索引對應】----------") print(frame)View Code
-------------獲取某列,然後統一賦一個值---------- pop year name age one 3 2020 張三 18 two 2 2021 李四 18 three 1 2022 王五 18 four 4 2023 趙六 18 -------------獲取某列,然後賦一個(可遞迴)值---------- pop year name age one 3 2020 張三 0 two 2 2021 李四 1 three 1 2022 王五 2 four 4 2023 趙六 3 -------------定義Series【值和索引對應】---------- pop year name age one 3 2020 張三 17.0 two 2 2021 李四 NaN three 1 2022 王五 18.0 four 4 2023 趙六 NaN輸出結果
4:dataframe新增一個列
為不存在的列賦值會建立一個新列。
def data_frame_03_a(): data = { 'name': ['張三', '李四', '王五', '趙六'], 'year': [2020, 2021, 2022, 2023], 'pop': [3, 2, 1, 4], } frame = pd.DataFrame(data, columns=['pop', 'year', 'name', 'age'], index=['one', 'two', 'three', 'four']) val = pd.Series([17, 18], index=['one', 'three', ]) frame['age'] = val print("-------------定義Series【值和索引對應】----------") print(frame) frame["has_age"] = frame.age > 0 print(frame)View Code
-------------定義Series【值和索引對應】---------- pop year name age one 3 2020 張三 17.0 two 2 2021 李四 NaN three 1 2022 王五 18.0 four 4 2023 趙六 NaN pop year name age has_age one 3 2020 張三 17.0 True two 2 2021 李四 NaN False three 1 2022 王五 18.0 True four 4 2023 趙六 NaN False輸出結果
5:dataframe 刪除列
關鍵字del用於刪除列。
def data_frame_03_d(): data = { 'name': ['張三', '李四', '王五', '趙六'], 'year': [2020, 2021, 2022, 2023], 'pop': [3, 2, 1, 4], } frame = pd.DataFrame(data, columns=['pop', 'year', 'name', 'age'], index=['one', 'two', 'three', 'four']) del frame["pop"] print(frame)View Code
year name age one 2020 張三 NaN two 2021 李四 NaN three 2022 王五 NaN four 2023 趙六 NaN輸出結果
6:loc和iloc
- loc的意思是基於標籤(label-based selection),輸入為標籤。在對資料進行切片操作時,loc與Python中 (:)的含義有差異,左閉右閉
- iloc的意思是基於索引(index-based selection),輸入為索引。在對資料進行切片操作時,iloc與Python中 (:)的含義相同,左閉右開
def data_frame_03_di(): # 另外一種常見的資料形式是巢狀字典,外層字典的鍵作為列,內層鍵作為行索引 # loc的意思是基於標籤(label-based selection),輸入為標籤。在對資料進行切片操作時,loc與Python中 (:)的含義有差異,左閉右閉 # iloc的意思是基於索引(index-based selection),輸入為索引。在對資料進行切片操作時,iloc與Python中 (:)的含義相同,左閉右開 data = { "name": {1: "張三", 3: "李四", 5: "王五", 7: "趙六"}, "year": {1: 2020, 3: 2021, 5: 2022, 7: 2023}, "pop": {1: 3, 3: 2, 5: 1, 40: 4} } frame = pd.DataFrame(data) print(frame) m1_row_by_iloc = frame.iloc[0:3, 1] print("-------------通過行號獲取多行----------") print(m1_row_by_iloc) m2_row_by_iloc = frame.loc[0:3, 'year'] print("-------------通過行號獲取多行----------") print(m2_row_by_iloc)View Code
name year pop 1 張三 2020.0 3.0 3 李四 2021.0 2.0 5 王五 2022.0 1.0 7 趙六 2023.0 NaN 40 NaN NaN 4.0 -------------通過行號獲取多行---------- 1 2020.0 3 2021.0 5 2022.0 Name: year, dtype: float64 -------------通過行號獲取多行---------- 1 2020.0 3 2021.0 Name: year, dtype: float64輸出結果