目錄
一、Pandas 簡介
二、Pandas 的安裝與導入
三、Pandas 的核心數據結構
(一)Series
(二)DataFrame
四、Pandas 數據讀取與寫入
(一)讀取數據
(二)寫入數據
五、數據清洗與預處理
(一)處理缺失值
(二)數據去重
(三)數據轉換
(四)數據合并與連接
六、數據探索與分析
(一)數據概覽
(二)數據分組與聚合
(三)數據篩選與排序
七、Pandas 的實際應用案例
(一)金融數據分析
(二)銷售數據分析
八、Pandas 的高級特性
(一)時間序列分析
(二)高級數據透視表
(三)數據管道操作
九、Pandas 的性能優化
十、Pandas 的局限性與注意事項
一、Pandas 簡介
Pandas 是一個開源的 Python 數據分析庫,由 Wes McKinney 于 2008 年創建。它的名字來源于 “panel data”(面板數據),這是一種在經濟學中常用的多維數據類型。Pandas 的目標是為 Python 提供一個功能強大、靈活易用的數據結構和數據分析工具,以滿足現實世界中復雜多樣的數據處理需求。
Pandas 的核心優勢在于其兩大主要數據結構:Series
和 DataFrame
。Series
是一個一維的標簽化數組,而 DataFrame
則是一個二維的表格型數據結構,類似于 Excel 中的表格或 SQL 中的表。這些數據結構使得數據的存儲、檢索、操作和分析變得更加直觀和高效。
二、Pandas 的安裝與導入
要使用 Pandas,首先需要確保它已正確安裝在你的 Python 環境中。可以通過以下方式進行安裝:
-
使用 pip 安裝 :在命令行中輸入 “pip install pandas”,pip 會自動下載并安裝 Pandas 及其依賴項。
-
使用 conda 安裝 :如果你使用 Anaconda 發行版,可以在命令行中輸入 “conda install pandas”,conda 會從其倉庫中安裝合適的 Pandas 版本。
安裝完成后,在 Python 腳本或交互式環境中,通過以下代碼導入 Pandas:
import pandas as pd
通常我們使用 “pd” 作為 Pandas 的別名,這樣在后續代碼中可以更簡潔地調用 Pandas 的函數和類。
三、Pandas 的核心數據結構
(一)Series
Series
是 Pandas 中的一維數據結構,類似于 NumPy 的一維數組,但帶有標簽。這些標簽可以是任何類型,如整數、字符串等,它們為數據提供了更直觀的索引方式。
創建 Series
的基本方法如下
import pandas as pd# 從列表創建 Series
data = [10, 20, 30, 40, 50]
s = pd.Series(data)
print(s)
0 10
1 20
2 30
3 40
4 50
dtype: int64
默認情況下,Series
的索引是從 0 開始的整數序列。你也可以自定義索引:
import pandas as pd# 從列表創建 Series 并自定義索引
data = [10, 20, 30, 40, 50]
index = ['a', 'b', 'c', 'd', 'e']
s = pd.Series(data, index=index)
print(s)
a 10
b 20
c 30
d 40
e 50
dtype: int64
訪問 Series
中的元素可以通過索引標簽或位置:
# 通過索引標簽訪問元素
print(s['b']) # 輸出 20# 通過位置訪問元素
print(s[2]) # 輸出 30
(二)DataFrame
DataFrame
是 Pandas 中的二維數據結構,類似于表格,包含行和列。它是 Pandas 最常用的數據結構之一,適合存儲和處理結構化數據。
創建 DataFrame
的基本方法如下:
import pandas as pd# 從字典創建 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David'],'Age': [25, 30, 35, 40],'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)
print(df)
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
3 David 40 Houston
DataFrame
的列可以通過列名進行訪問和操作
# 訪問某一列
print(df['Name'])
0 Alice
1 Bob
2 Charlie
3 David
Name: Name, dtype: object
你也可以同時訪問多列:
# 訪問多列
print(df[['Name', 'Age']])
Name Age
0 Alice 25
1 Bob 30
2 Charlie 35
3 David 40
DataFrame
的行可以通過 iloc
(基于整數位置索引)或 loc
(基于標簽索引)進行訪問:
# 通過 iloc 訪問第 2 行
print(df.iloc[2])
Name Charlie
Age 35
City Chicago
Name: 2, dtype: object
# 通過 loc 訪問索引標簽為 1 的行
print(df.loc[1])
輸出結果:
Name Bob
Age 30
City Los Angeles
Name: 1, dtype: object
四、Pandas 數據讀取與寫入
Pandas 提供了豐富的函數用于讀取和寫入各種格式的數據,如 CSV、Excel、SQL 數據庫等。
(一)讀取數據
-
讀取 CSV 文件 :
import pandas as pd# 讀取 CSV 文件
df = pd.read_csv('data.csv')
print(df.head()) # 顯示前 5 行數據
-
讀取 Excel 文件 :
import pandas as pd# 讀取 Excel 文件
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
print(df.head())
-
從 SQL 數據庫讀取數據 :
import pandas as pd
import sqlite3# 連接到 SQLite 數據庫
conn = sqlite3.connect('database.db')# 從數據庫讀取數據
df = pd.read_sql_query('SELECT * FROM table_name', conn)
print(df.head())# 關閉數據庫連接
conn.close()
(二)寫入數據
-
寫入 CSV 文件 :
import pandas as pd# 創建 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David'],'Age': [25, 30, 35, 40],'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)# 將 DataFrame 寫入 CSV 文件
df.to_csv('output.csv', index=False)
-
寫入 Excel 文件 :
import pandas as pd# 創建 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David'],'Age': [25, 30, 35, 40],'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)# 將 DataFrame 寫入 Excel 文件
df.to_excel('output.xlsx', sheet_name='Sheet1', index=False)
-
寫入 SQL 數據庫 :
import pandas as pd
import sqlite3# 創建 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David'],'Age': [25, 30, 35, 40],'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)# 連接到 SQLite 數據庫
conn = sqlite3.connect('database.db')# 將 DataFrame 寫入數據庫
df.to_sql('table_name', conn, if_exists='replace', index=False)# 關閉數據庫連接
conn.close()
五、數據清洗與預處理
在實際數據分析中,數據往往不完整、不一致或包含錯誤,需要進行清洗和預處理,以確保數據的質量。Pandas 提供了許多工具來幫助完成這些任務。
(一)處理缺失值
缺失值是數據清洗中常見的問題,Pandas 提供了檢測、刪除和填充缺失值的函數。
-
檢測缺失值 :
import pandas as pd# 創建包含缺失值的 DataFrame
data = {'A': [1, 2, None, 4],'B': [5, None, 7, 8],'C': [9, 10, 11, None]
}
df = pd.DataFrame(data)# 檢測缺失值
print(df.isnull())
輸出結果:
A B C
0 False False False
1 False True False
2 True False False
3 False False True
-
刪除缺失值 :
# 刪除包含缺失值的行
df.dropna(inplace=True)
print(df)
-
填充缺失值 :
# 用 0 填充缺失值
df.fillna(0, inplace=True)
print(df)
(二)數據去重
重復數據可能導致分析結果的偏差,Pandas 提供了檢測和刪除重復數據的功能。
-
檢測重復數據 :
import pandas as pd# 創建包含重復數據的 DataFrame
data = {'A': [1, 2, 2, 4],'B': [5, 6, 6, 8],'C': [9, 10, 10, 12]
}
df = pd.DataFrame(data)# 檢測重復行
print(df.duplicated())
0 False
1 False
2 True
3 False
dtype: bool
-
刪除重復數據 :
# 刪除重復行
df.drop_duplicates(inplace=True)
print(df)
(三)數據轉換
數據轉換是將數據從一種形式轉換為另一種形式的過程,包括數據類型轉換、數值縮放、編碼等。
-
數據類型轉換 :
import pandas as pd# 創建 DataFrame
data = {'A': [1, 2, 3, 4],'B': [5.0, 6.5, 7.2, 8.9],'C': ['apple', 'banana', 'orange', 'grape']
}
df = pd.DataFrame(data)# 將列 A 轉換為浮點型
df['A'] = df['A'].astype(float)# 將列 B 轉換為整型(向下取整)
df['B'] = df['B'].astype(int)print(df.dtypes)
輸出結果:
A float64
B int32
C object
dtype: object
-
數值縮放 :
import pandas as pd# 創建 DataFrame
data = {'A': [10, 20, 30, 40, 50]
}
df = pd.DataFrame(data)# 使用 Min-Max 縮放將數據縮放到 [0, 1] 范圍
df['A'] = (df['A'] - df['A'].min()) / (df['A'].max() - df['A'].min())
print(df)
輸出結果:
A
0 0.0
1 0.25
2 0.5
3 0.75
4 1.0
-
編碼分類數據 :
import pandas as pd# 創建包含分類數據的 DataFrame
data = {'Color': ['Red', 'Blue', 'Green', 'Red', 'Blue']
}
df = pd.DataFrame(data)# 使用 one-hot 編碼轉換分類數據
df = pd.get_dummies(df, columns=['Color'])
print(df)
輸出結果:
Color_Blue Color_Green Color_Red
0 0 0 1
1 1 0 0
2 0 1 0
3 0 0 1
4 1 0 0
(四)數據合并與連接
在數據分析中,通常需要將多個數據集合并成一個,Pandas 提供了多種方法來實現數據的合并和連接。
-
合并數據集 :
import pandas as pd# 創建兩個 DataFrame
data1 = {'Key': ['A', 'B', 'C', 'D'],'Value1': [10, 20, 30, 40]
}
df1 = pd.DataFrame(data1)data2 = {'Key': ['B', 'D', 'E', 'F'],'Value2': [50, 60, 70, 80]
}
df2 = pd.DataFrame(data2)# 基于 'Key' 列合并兩個 DataFrame
merged_df = pd.merge(df1, df2, on='Key', how='inner')
print(merged_df)
輸出結果:
Key Value1 Value2
0 B 20 50
1 D 40 60
how
參數可以取以下值:
-
inner
:內連接(默認),只保留兩個數據集中共有的鍵。 -
outer
:外連接,保留兩個數據集中的所有鍵,缺失值用 NaN 填充。 -
left
:左連接,保留左數據集中的所有鍵,右數據集中缺失的鍵用 NaN 填充。 -
right
:右連接,保留右數據集中的所有鍵,左數據集中缺失的鍵用 NaN 填充。 -
連接數據集 :
import pandas as pd# 創建兩個 DataFrame
data1 = {'A': [1, 2, 3],'B': [4, 5, 6]
}
df1 = pd.DataFrame(data1, index=['X', 'Y', 'Z'])data2 = {'C': [7, 8, 9],'D': [10, 11, 12]
}
df2 = pd.DataFrame(data2, index=['Y', 'Z', 'W'])# 按行連接兩個 DataFrame
concatenated_df = pd.concat([df1, df2], axis=0)
print(concatenated_df)
輸出結果:
A B C D
X 1.0 4.0 NaN NaN
Y 2.0 5.0 7.0 10.0
Z 3.0 6.0 8.0 11.0
W NaN NaN 9.0 12.0
axis
參數指定連接的方向,axis=0
表示按行連接,axis=1
表示按列連接。
六、數據探索與分析
Pandas 提供了豐富的函數用于數據的探索和分析,幫助你快速了解數據的基本特征和統計信息。
(一)數據概覽
-
查看前幾行數據 :
import pandas as pd# 創建 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David'],'Age': [25, 30, 35, 40],'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)# 查看前 3 行數據
print(df.head(3))
輸出結果:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
-
查看數據的基本信息 :
# 查看數據的基本信息
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 3 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 Name 4 non-null object1 Age 4 non-null int64 2 City 4 non-null object
dtypes: int64(1), object(2)
memory usage: 208.0+ bytes
-
查看數據的統計摘要 :
# 查看數據的統計摘要
print(df.describe())
Age
count 4.000000
mean 32.500000
std 6.454972
min 25.000000
25% 28.750000
50% 32.500000
75% 36.250000
max 40.000000
(二)數據分組與聚合
數據分組與聚合是數據分析中的常見操作,Pandas 提供了方便的 groupby
和聚合函數來實現這些功能。
-
按某一列分組并求和 :
import pandas as pd# 創建 DataFrame
data = {'Category': ['A', 'B', 'A', 'B', 'A', 'B'],'Value': [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)# 按 'Category' 列分組,并對 'Value' 列求和
grouped_df = df.groupby('Category')['Value'].sum()
print(grouped_df)
Category
A 90
B 120
Name: Value, dtype: int64
-
按多列分組并計算多種聚合統計量 :
import pandas as pd# 創建 DataFrame
data = {'Category': ['A', 'B', 'A', 'B', 'A', 'B'],'Subcategory': ['X', 'Y', 'X', 'Y', 'X', 'Y'],'Value': [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)# 按 'Category' 和 'Subcategory' 列分組,并計算 'Value' 列的均值和總和
grouped_df = df.groupby(['Category', 'Subcategory'])['Value'].agg(['mean', 'sum'])
print(grouped_df)
mean sum
Category Subcategory
A X 30 90
B Y 40 120
(三)數據篩選與排序
-
數據篩選 :
import pandas as pd# 創建 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],'Age': [25, 30, 35, 40, 28],'City': ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Seattle']
}
df = pd.DataFrame(data)# 篩選年齡大于 30 的行
filtered_df = df[df['Age'] > 30]
print(filtered_df)
Name Age City
2 Charlie 35 Chicago
3 David 40 Houston
-
數據排序 :
# 按年齡降序排序
sorted_df = df.sort_values(by='Age', ascending=False)
print(sorted_df)
Name Age City
3 David 40 Houston
2 Charlie 35 Chicago
1 Bob 30 Los Angeles
4 Eve 28 Seattle
0 Alice 25 New York
七、Pandas 的實際應用案例
(一)金融數據分析
假設我們有一個股票價格數據集,包含日期、開盤價、收盤價、最高價、最低價和成交量等信息。我們可以使用 Pandas 對這些數據進行分析。
import pandas as pd# 讀取股票價格數據
df = pd.read_csv('stock_prices.csv')# 轉換日期列為日期時間類型
df['Date'] = pd.to_datetime(df['Date'])# 將日期列設置為索引
df.set_index('Date', inplace=True)# 計算每日收益率
df['Return'] = df['Close'].pct_change() * 100# 繪制收盤價和收益率圖
import matplotlib.pyplot as pltfig, ax1 = plt.subplots()ax1.plot(df['Close'], label='Close Price', color='blue')
ax1.set_xlabel('Date')
ax1.set_ylabel('Close Price', color='blue')
ax1.tick_params(axis='y', labelcolor='blue')ax2 = ax1.twinx()
ax2.plot(df['Return'], label='Daily Return', color='red', linestyle='--')
ax2.set_ylabel('Daily Return (%)', color='red')
ax2.tick_params(axis='y', labelcolor='red')plt.title('Stock Price and Daily Return')
fig.tight_layout()
plt.show()
(二)銷售數據分析
假設我們有一個銷售數據集,包含產品名稱、銷售日期、銷售數量、銷售價格等信息。我們可以使用 Pandas 分析產品的銷售趨勢和收益情況。
import pandas as pd# 讀取銷售數據
df = pd.read_csv('sales_data.csv')# 轉換銷售日期列為日期時間類型
df['Sale Date'] = pd.to_datetime(df['Sale Date'])# 按月統計銷售數量和銷售額
monthly_sales = df.resample('M', on='Sale Date').agg({'Quantity': 'sum','Price': 'sum'
})
monthly_sales.columns = ['Total Quantity', 'Total Sales']# 繪制月度銷售趨勢圖
import matplotlib.pyplot as pltmonthly_sales.plot(kind='line', secondary_y='Total Sales')
plt.title('Monthly Sales Trend')
plt.xlabel('Month')
plt.ylabel('Total Quantity')
plt.gcf().axes[1].set_ylabel('Total Sales')
plt.tight_layout()
plt.show()
八、Pandas 的高級特性
(一)時間序列分析
Pandas 提供了強大的時間序列處理功能,包括日期范圍生成、時間索引操作、時間序列重采樣等。
-
生成日期范圍 :
import pandas as pd# 生成從 2023-01-01 到 2023-12-31 的日期范圍
date_range = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
print(date_range)
-
時間序列重采樣 :
import pandas as pd# 創建時間序列數據
index = pd.date_range(start='2023-01-01', periods=100, freq='D')
data = np.random.randn(100)
ts = pd.Series(data, index=index)# 按周重采樣并計算周平均值
weekly_mean = ts.resample('W').mean()
print(weekly_mean)
(二)高級數據透視表
數據透視表是一種用于數據匯總和分析的強大工具,Pandas 提供了靈活的 pivot_table
函數來創建數據透視表。
import pandas as pd# 創建示例數據
data = {'Product': ['A', 'B', 'A', 'B', 'A', 'B'],'Category': ['X', 'X', 'Y', 'Y', 'X', 'Y'],'Region': ['North', 'South', 'East', 'West', 'North', 'South'],'Sales': [100, 150, 200, 180, 120, 160]
}
df = pd.DataFrame(data)# 創建數據透視表,按產品和類別匯總銷售額
pivot_table = pd.pivot_table(df, values='Sales', index='Product', columns='Category', aggfunc='sum', fill_value=0)
print(pivot_table)
Category X Y
Product
A 220 200
B 150 340
(三)數據管道操作
數據管道是一種將多個數據處理步驟組合在一起的技術,Pandas 支持使用 apply
函數實現數據管道操作。
import pandas as pd# 創建示例數據
data = {'Text': ['apple', 'banana', 'orange', 'grape', 'pineapple']
}
df = pd.DataFrame(data)# 定義數據處理管道函數
def text_processing(text):# 轉換為小寫text = text.lower()# 替換特定字符text = text.replace('a', 'X')# 返回處理后的文本return text# 應用數據處理管道
df['Processed Text'] = df['Text'].apply(text_processing)
print(df)
Text Processed Text
0 apple Xpple
1 banana bXnXnX
2 orange orgXnge
3 grape grXpe
4 pineapple pXnXpXle
九、Pandas 的性能優化
在處理大規模數據時,Pandas 的性能可能會受到挑戰。以下是一些優化 Pandas 性能的技巧:
-
使用合適的數據類型 :選擇合適的數據類型可以減少內存占用,提高計算速度。例如,將整數列轉換為更小的數據類型:
import pandas as pd# 創建 DataFrame
df = pd.DataFrame({'A': np.random.randint(0, 100, size=1000000)
})# 轉換列 A 的數據類型為更小的整數類型
df['A'] = df['A'].astype(np.int8)
-
避免使用 apply 函數 :
apply
函數在大多數情況下比矢量化操作慢得多。盡量使用 Pandas 的內置矢量化函數:
import pandas as pd# 創建 DataFrame
df = pd.DataFrame({'A': np.random.randn(1000000)
})# 使用矢量化操作計算平方(推薦)
df['A_squared'] = df['A'] ** 2# 使用 apply 函數計算平方(不推薦)
# df['A_squared'] = df['A'].apply(lambda x: x ** 2)
-
使用 chunksize 讀取大文件 :當處理無法一次性加載到內存的大文件時,可以使用
chunksize
參數分塊讀取:
import pandas as pd# 分塊讀取 CSV 文件
chunk_size = 10000
for chunk in pd.read_csv('large_file.csv', chunksize=chunk_size):# 對每個數據塊進行處理process(chunk)
十、Pandas 的局限性與注意事項
盡管 Pandas 功能強大,但它也有一些局限性和需要注意的地方:
-
處理大規模數據的性能瓶頸 :對于非常大的數據集(如數十億條記錄),Pandas 可能會遇到性能瓶頸。在這種情況下,可以考慮使用分布式計算框架(如 Dask、Spark)或數據庫解決方案。
-
復雜的文本處理能力有限 :對于復雜的文本處理任務,Pandas 的功能可能不如專門的文本處理庫(如 NLTK、spaCy)強大。在這種情況下,可以結合使用 Pandas 和其他文本處理庫。
-
實時數據處理的適用性有限 :Pandas 主要設計用于批處理數據,對于實時數據處理任務可能不太適用。實時數據處理通常需要使用流處理框架(如 Apache Kafka、Apache Flink)