前言
? ? ? ? 總結才是知識,作者習慣不好,不會總結,導致函數一旦不使用就會忘記怎么使用,特此寫了本文,用于給自己一個復習的資料.
? ? 提示:如果你是小白,每個代碼請自己敲打。
一 pandas的介紹
Pandas is a python library used for working with data sets
It has functions for analyzing ,cleaning,exploring and mainpulating data
The name "pandas" has a reference to both "Panel Data" and "Python Data Analysis" and was created by Wes Mckinney in 2008
二 pandas Series
Series 是一個包含任何數據類型的數據的一維數組,就像表中的一列。(注意:首字母大寫)
2.1 語法:
import pandas as pdpd.Series(data,index,dtype)
# 參數介紹
# data :一維數組(ndarray 類型)
# index:數據索引標簽(可以是字符串類型、數字或者混合),默認是從0開始,可以重復
# dtype:數據類型,會根據數組內值類型返回結果
- dtype :
數據類型 ? ?描述 ? ? ?內存占用 ? ? ? ?精度范圍 ? ? ? ? ? ? ?使用場景
'i4' ? ?32 位整數 ? ? ?4 字節 ? ? ? ?-2^31 至 2^31-1 ? ? ?小范圍整數,如索引或計數器
'i8' ? ?64 位整數 ? ? ?8 字節 ? ? ? ?-2^63 至 2^63-1 ? ? ?大范圍整數,如時間戳或 ID
'f4' ? ?32 位浮點數 ? ? 4 字節 ? ? ? ?約 7 位有效數字 ? ? ? ?低精度計算,如圖像處理
'f8' ? ?64 位浮點數 ? ? 8 字節 ? ? ? ?約 15 位有效數字 ? ? 高精度計算,如科學分析
2.2 如何創建Series
import pandas as pd
import numpy as np
# 創建空的Series
s_1 = pd.Series() # 所有的值都是默認值 dtype:object# 使用numpy中的ndarray創建 Series
arry = np.random.randn(5)
s_2 = pd.Series(data=arry)# 使用列表創建
l_1 = [1,2,3]
s_3=pd.Series(data=l_1)# 使用字典創建
dict1 = {"小張":1,"小明":2,"小紅":3}
s_4=pd.Series(data=dict1)# 使用標量創建
s_5= pd.Series(data=10,index=range(0,10))
2.3 針對Series的操作
- ?修改index
s_4.index=[0,1,2]print(s_4)
- #刪除特定的值
Series.drop(labels=None, *, axis=0, index=None,level=None, inplace=False, errors='raise')
## 參數
# ? labels: 單個標簽或標簽列表。指定要從 Series 中刪除的索引標簽。
# ? axis: 只能為 0 或 index,因為 Series 是一維數據結構,僅支持沿索引方向操作。
# ? index: 替代參數,用于直接指定要刪除的索引。與 labels 功能相同,但更直觀。
# ? level: 如果索引是 MultiIndex,則可以指定刪除哪一層級的索引。
# ? inplace: 布爾值。如果設置為 True,則直接在原 Series 上進行修改;否則返回一個新的 Series。
# ? errors: 字符串。如果設置為 'ignore',當指定的標簽不存在時不會拋出錯誤,而是忽略該標簽;默認值為 'raise',會拋出錯誤。print(s_4.drop(labels=0))
print(s_4.drop(index=[0,1]))
print(s_4) # 因為inplace=False,因此不會改變Series# 切片操作-等同于列表
print(s_4[-2:])
- 基本運算(+-*/)index為Key
## 注意:如果索引大小不同,則較小索引的Series中與較大Serise中相同index值為NON
#+
print(s_2+s_5)
print(s_2.add(s_5))
#-
print(s_2-s_5)
print(s_2.sub(s_5))
#*
print(s_2*s_5)
print(s_2.mul(s_5))
#/
print(s_2/s_5)
print(s_2.div(s_5))
#統計
print(s_2.describe())
- ?特殊方法——where (對于滿足不等式的元素重新賦值)
#創建一個簡單的 Series
s = pd.Series([10, 20, 30, 40, 50])#替換所有小于 30 的值為 NaN
result1 = s.where(s >= 30)
print("示例 1:")
print(result1)#替換所有小于 30 的值為 -1
result2 = s.where(s >= 30, -1)
print("\n示例 2:")
print(result2)#使用另一個 Series 作為替代值
alt_values = pd.Series([-1, -2, -3, -4, -5])
result3 = s.where(s >= 30, alt_values)
print("\n示例 3:")
print(result3)
- concat 拼接兩個Series
import pandas as pd
s1 = pd.Series([10, 20, 30, 40, 50])
s2 = pd.Series([11, 20, 30, 40, 50])
s3 = pd.concat([s1, s2], ignore_index=True)
print(s3)
三 DataFrame
之前介紹了 Series,在表格中相當于一列的值,但是我們操作表的時候時既有橫向的還有列項的。
那現在就需要引入另外一個定義 DataFrame,當讀取一個表格的時候會將數據直接轉換成DataFrame格式
- DataFrame:A Pandas DataFrame is a 2 dimensional data structure, like a 2 dimensional array ,or a table with rows and columns
import pandas as pdpd.DataFrame(data=None,index=None,columns=None)data:數據
index:設置行的名稱
columns: 設置列的名稱
- ?如何創建 DataFrmae
# 使用字典創建
import pandas as pd
import numpy as np
dict1 ?= {"xiaoming":[1,2,3],"xiaohong":[3,2,1]}
df1 = pd.DataFrame(dict1)# 使用array創建
data1 = np.arange(18).reshape(3,6)
df2 = pd.DataFrame(data1)
看了很多文章,在介紹什么是DataFrame時候會介紹如何探尋DataFrame中是數據,我認為可以放在數據處理和分析的時候介紹。
四 數據處理
4.1 數據的獲取
因業務的不同,數據來源不同,因此獲取數據的方式也不一樣,數據來源:數據庫,excel(xlwx,hmlx,csv),txt等格式
4.11 從數據庫獲取數據
import pyodbc
from contextlib import contextmanager
from concurrent.futures import ThreadPoolExecutor
import pandas as pd
server = '替換成你的數據庫所在的服務器名稱'
database = '數據庫名稱'
username = '用戶名'
password = '登陸密碼'
driver = '{ODBC Driver 17 for SQL Server}'
# 不同版本的ODBC驅動
#driver = '{ODBC Driver 17 for SQL Server}' # 最新版本
#driver = '{ODBC Driver 13 for SQL Server}' # 較舊版本
#driver = '{SQL Server}' # 系統自帶的基礎驅動
#driver = '{SQL Server Native Client 11.0}' # Native Client驅動
# 創建連接字符串
conn_str = f'DRIVER={driver};SERVER={server};DATABASE={database};UID={username};PWD={password}'# 創建連接池
pool = ThreadPoolExecutor(max_workers=5)@contextmanager
def get_connection():conn = pyodbc.connect(conn_str)try:yield connfinally:conn.close()def execute_query(query, params=None):with get_connection() as conn:cursor = conn.cursor()if params:cursor.execute(query, params)else:cursor.execute(query)return cursor.fetchall()
def query_to_dataframe(query, params=None):with get_connection() as conn:try:if params:df = pd.read_sql(query, conn, params=params)else:df = pd.read_sql(query, conn)return dfexcept (pyodbc.Error, pd.io.sql.DatabaseError) as e:print(f"Error executing query: {e}")return None
## 場景1:需要原始數據進行簡單處理
raw_data = execute_query("SELECT count(*) FROM users")
user_count = raw_data[0][0]# 場景2:需要進行數據分析
df = query_to_dataframe("SELECT * FROM sales_data WHERE year = 2023")
monthly_sales = df.groupby('month').sum()# 場景3:需要自定義數據庫操作
with get_connection() as conn:cursor = conn.cursor()cursor.execute("INSERT INTO logs VALUES (?, ?)", [timestamp, message])conn.commit()
# 場景4:從數據庫獲取數據并轉換成 DataFrame格式
query = "select * from 表名稱"
project = pd.read_sql(query, pyodbc.connect(conn_str))
如果你不知道怎么書寫,請跟AI交流一下,讓它幫你出一個注意
4.12 從excel(xlsx和csv)獲取數據
注意:如果是公司Teams上的文件夾中的數據,如果想直接使用pandas讀取,需要將Teams上的表格同步到自己的ONEDrive中,然后獲取本地電腦中的文件位置,進行讀取。會產生同步問題。
-
相對路徑和絕對路徑
假設當前目錄是 C:\Users\張三\project
相對路徑示例
"data.xlsx" ? ? ? ? ? ? ?#當前目錄下的文件
"./data.xlsx" ? ? ? ? ? ?#同上,./表示當前目錄
"../documents/file.xlsx" #上級目錄下的documents文件夾中的文件
"subfolder/image.png" ? #當前目錄下subfolder中的文件
"../../backup/data.sql" #上級的上級目錄下backup文件夾中的文件
絕對路徑:從文件系統根目錄開始的完整路徑
- /和\
特性 | / ?(正斜杠) | \ ?(反斜杠) |
---|---|---|
原生系統 | Unix/Linux/macOS | Windows |
Python兼容性 | 所有系統都支持 ? | 僅Windows原生,但Python可處理 |
URL使用 | 標準格式 ? | 不適用 ? |
轉義問題 | 無問題 ? | 需要轉義?\\ ?或使用?r"" |
跨平臺性 | 優秀 ? | 較差 ?? |
推薦度 | 高度推薦 ? | 特定場景使用 |
?因此路徑有三種書寫方式
/ | "./data.xlsx" |
\\ | ".\\data.xlsx" |
\ | r".\data.xlsx" |
- 函數 read_excel
df = pd.read_excel(
'data.xlsx', # 文件路徑
sheet_name=0, # 可以是sheet的名稱也可以是數字(0,1,2,3,,,,,)
header=0, # 標題行位置
index_col=None, # 索引列
usecols=None, # 指定讀取的列
dtype=None, # 數據類型
engine=None, # 讀取引擎
skiprows=None, # 跳過的行數
nrows=None # 讀取的行數
)
- 函數 read_csv
df = pd.read_csv('data.csv', # 文件路徑或URLsep=',', # 分隔符delimiter=None, # 分隔符的別名header='infer', # 標題行位置names=None, # 列名列表index_col=None, # 索引列usecols=None, # 指定讀取的列dtype=None, # 數據類型encoding=None, # 文件編碼nrows=None, # 讀取的行數skiprows=None # 跳過的行數
)