名人說:路漫漫其修遠兮,吾將上下而求索。—— 屈原《離騷》
創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder😊)
訂閱專欄:《Python星球日記》
目錄
- 一、引言
- 二、數據分組與聚合
- 1. 分組操作基礎
- 按單列分組
- 按多列分組
- 2. 聚合函數
- 單一聚合函數
- 多個聚合函數
- 對不同列應用不同的聚合函數
- 3. 轉換與過濾
- 轉換操作
- 過濾操作
- 三、排序與排名
- 1. 數據排序
- 按值排序 - sort_values()
- 按索引排序 - sort_index()
- 2. 數據排名
- 處理并列情況
- 四、時間序列分析
- 1. 時間戳與時間段
- 2. 創建時間序列數據
- 3. 時間序列索引與切片
- 4. 重采樣
- 5. 移動窗口函數
- 五、實戰練習:銷售數據分析
- 1. 準備數據
- 2. 分組分析
- 3. 時間序列分析
- 4. 數據可視化
- 六、總結與拓展
- 1. 關鍵知識點回顧
- 2. 實際應用場景
- 3. 學習資源推薦
👋 專欄介紹: Python星球日記專欄介紹(持續更新ing)
? 上一篇: 《Python星球日記》第24天:Pandas 數據清洗
🌟引言: 歡迎來到Python星球🪐的第25天!
今天我們將深入學習Pandas的高級數據分析功能,包括數據分組、聚合操作、排序與排名以及時間序列分析。這些是數據分析工作中的核心技能,掌握它們將大大提升你的數據處理能力。
一、引言
在前面的學習中,我們已經了解了Pandas的基礎知識,包括Series和DataFrame的創建、基本操作和數據清洗等。今天,我們將進一步探索Pandas提供的高級數據分析功能,學習如何從數據中提取更深層次的信息和洞察。
數據分析是數據科學工作流程中的核心環節,而Pandas提供了豐富的工具和函數來支持各種分析需求。通過本文的學習,你將掌握如何對數據進行分組分析、排序排名以及時間序列處理,這些都是實際數據分析項目中經常用到的技能。
首先,讓我們導入必要的庫:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt# 設置中文顯示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
二、數據分組與聚合
數據分組和聚合是數據分析中最常用的操作之一,它允許我們按照某一列或多列的值將數據分為多個組,然后對每組數據應用聚合函數。
1. 分組操作基礎
分組操作的核心是groupby()
函數,它根據指定的一個或多個列將DataFrame分割成不同的組。
讓我們創建一個銷售數據示例:
# 創建示例銷售數據
data = {'日期': pd.date_range(start='2023-01-01', periods=20, freq='D'),'產品': ['A', 'B', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],'區域': ['東部', '東部', '南部', '南部', '東部', '西部', '西部', '南部', '東部', '南部','西部', '東部', '南部', '西部', '東部', '南部', '西部', '東部', '南部', '西部'],'銷售額': np.random.randint(1000, 5000, size=20),'數量': np.random.randint(10, 100, size=20)
}df = pd.DataFrame(data)
print(df.head())
輸出結果:
日期 產品 區域 銷售額 數量
0 2023-01-01 A 東部 3416 56
1 2023-01-02 B 東部 4713 67
2 2023-01-03 A 南部 2965 31
3 2023-01-04 B 南部 1743 25
4 2023-01-05 C 東部 4350 78
按單列分組
最簡單的分組是按單個列進行分組:
# 按產品分組并計算銷售額總和
product_sales = df.groupby('產品')['銷售額'].sum()
print(product_sales)
輸出結果:
產品
A 14986
B 20165
C 17354
Name: 銷售額, dtype: int64
按多列分組
我們也可以按多個列進行分組:
# 按產品和區域分組,計算銷售額總和
product_region_sales = df.groupby(['產品', '區域'])['銷售額'].sum()
print(product_region_sales)
輸出結果:
產品 區域
A 東部 9874南部 2965西部 2147
B 東部 4713南部 11709西部 3743
C 東部 4350南部 4219西部 8785
Name: 銷售額, dtype: int64
2. 聚合函數
聚合函數是對分組后的數據執行計算的函數。Pandas提供了多種內置的聚合函數:
單一聚合函數
# 按產品分組,計算銷售額的平均值
avg_sales = df.groupby('產品')['銷售額'].mean()
print(avg_sales)
輸出結果:
產品
A 2997.2
B 4033.0
C 3470.8
Name: 銷售額, dtype: float64
多個聚合函數
# 按產品分組,同時計算銷售額的多個統計量
sales_stats = df.groupby('產品')['銷售額'].agg(['sum', 'mean', 'count', 'max', 'min'])
print(sales_stats)
輸出結果:
sum mean count max min
產品
A 14986 2997.2 5 4217 1983
B 20165 4033.0 5 4713 1743
C 17354 3470.8 5 4350 2631
對不同列應用不同的聚合函數
# 對不同列應用不同的聚合函數
agg_result = df.groupby('產品').agg({'銷售額': ['sum', 'mean'],'數量': ['count', 'max', 'min']
})
print(agg_result)
輸出結果:
銷售額 數量 sum mean count max min
產品
A 14986 2997.2 5 89 21
B 20165 4033.0 5 92 25
C 17354 3470.8 5 94 32
3. 轉換與過濾
除了聚合,groupby
對象還支持轉換和過濾操作:
轉換操作
轉換操作會返回與原DataFrame形狀相同的結果:
# 計算每個產品的銷售額占該產品總銷售額的百分比
df['銷售額百分比'] = df.groupby('產品')['銷售額'].transform(lambda x: x / x.sum() * 100
)
print(df[['產品', '銷售額', '銷售額百分比']].head(10))
過濾操作
過濾操作用于篩選滿足條件的組:
# 篩選出平均銷售額大于3000的產品組
filtered_groups = df.groupby('產品').filter(lambda x: x['銷售額'].mean() > 3000)
print(filtered_groups['產品'].unique())
三、排序與排名
數據分析中,排序和排名是非常常用的操作,可以幫助我們更好地理解數據的分布和相對位置。
1. 數據排序
Pandas提供了兩種主要的排序方法:按值排序和按索引排序。
按值排序 - sort_values()
# 按銷售額降序排序
df_sorted = df.sort_values(by='銷售額', ascending=False)
print(df_sorted[['產品', '區域', '銷售額']].head())# 按多列排序:先按產品排序,再按銷售額降序排序
df_multi_sorted = df.sort_values(by=['產品', '銷售額'], ascending=[True, False])
print(df_multi_sorted[['產品', '銷售額']].head())
按索引排序 - sort_index()
# 先將產品設為索引,然后按索引排序
df_idx = df.set_index('產品')
df_idx_sorted = df_idx.sort_index()
print(df_idx_sorted.head())
2. 數據排名
排名是一種將數據值轉換為其相對位置的方法。Pandas的rank()
函數提供了靈活的排名功能:
# 對銷售額進行排名
df['銷售額排名'] = df['銷售額'].rank(ascending=False) # 降序排名,銷售額最高的排名為1
print(df[['產品', '銷售額', '銷售額排名']].sort_values('銷售額排名').head())
處理并列情況
當存在相同值時,rank()
函數提供多種處理方式:
# 創建包含重復值的Series
s = pd.Series([7, 2, 7, 3, 7, 4])# 不同的處理并列的方式
print("默認(average):", s.rank())
print("min方法:", s.rank(method='min'))
print("max方法:", s.rank(method='max'))
print("first方法:", s.rank(method='first'))
print("dense方法:", s.rank(method='dense'))
輸出結果:
默認(average): [4.0, 1.0, 4.0, 2.0, 4.0, 3.0]
min方法: [3.0, 1.0, 3.0, 2.0, 3.0, 3.0]
max方法: [5.0, 1.0, 5.0, 2.0, 5.0, 3.0]
first方法: [3.0, 1.0, 4.0, 2.0, 5.0, 3.0]
dense方法: [3.0, 1.0, 3.0, 2.0, 3.0, 2.0]
四、時間序列分析
時間序列數據是按時間順序索引的數據,在金融、氣象、銷售等領域非常常見。Pandas提供了強大的時間序列處理功能。
1. 時間戳與時間段
Pandas有兩種主要的時間相關對象:
- Timestamp:表示時間點,類似于Python的
datetime
- Period:表示時間段,如"2023年1月"或"2023年第一季度"
# 創建時間戳
ts = pd.Timestamp('2023-01-15 12:30:00')
print(ts)# 創建時間段
period = pd.Period('2023-01', freq='M') # 月度頻率
print(period)
2. 創建時間序列數據
我們可以通過多種方式創建時間序列數據:
# 創建日期范圍
date_range = pd.date_range(start='2023-01-01', periods=10, freq='D')
print(date_range)# 創建帶時間序列索引的數據
ts_data = pd.Series(np.random.randn(10), index=date_range)
print(ts_data)
3. 時間序列索引與切片
時間序列數據可以使用時間進行索引和切片:
# 準備一年的每日數據
daily_data = pd.Series(np.random.rand(365),index=pd.date_range(start='2023-01-01', periods=365, freq='D')
)# 使用時間索引
print(daily_data['2023-02-14']) # 查看特定日期的數據# 時間范圍切片
print(daily_data['2023-03-01':'2023-03-07']) # 查看一周的數據# 使用年、月、日等屬性進行篩選
march_data = daily_data[daily_data.index.month == 3] # 篩選3月的數據
print(march_data)
4. 重采樣
重采樣是改變時間序列頻率的過程:
- 升采樣:從低頻到高頻(如月→日)
- 降采樣:從高頻到低頻(如日→月)
# 準備每日銷售數據
daily_sales = pd.Series(np.random.randint(100, 500, size=365),index=pd.date_range(start='2023-01-01', periods=365, freq='D')
)# 降采樣:日→月,求和
monthly_sales = daily_sales.resample('M').sum()
print(monthly_sales)# 降采樣:日→周,求平均
weekly_sales = daily_sales.resample('W').mean()
print(weekly_sales.head())# 升采樣:月→日,填充
monthly_data = pd.Series([1000, 1200, 1500, 1800, 2100, 2400],index=pd.date_range(start='2023-01-31', periods=6, freq='M')
)
daily_filled = monthly_data.resample('D').ffill() # 前向填充
print(daily_filled.head())
5. 移動窗口函數
移動窗口函數是時間序列分析中非常有用的工具:
# 7天移動平均
sales_7d_ma = daily_sales.rolling(window=7).mean()
print(sales_7d_ma.head(10))# 30天移動平均
sales_30d_ma = daily_sales.rolling(window=30, min_periods=1).mean()
print(sales_30d_ma.head())# 累計統計
cumulative_sales = daily_sales.expanding().sum()
print(cumulative_sales.head())
五、實戰練習:銷售數據分析
現在,讓我們綜合運用所學知識,對銷售數據進行分析和可視化。
1. 準備數據
import pandas as pd
import numpy as np# 創建更完整的銷售數據
np.random.seed(42) # 設置隨機種子以確保結果可重現# 創建日期范圍:2023年全年
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')# 產品類別
products = ['電子產品', '服裝', '食品', '家居']# 創建空的DataFrame
sales_data = []# 生成數據
for date in dates:# 為每個產品生成銷售記錄for product in products:# 模擬周末銷量增加weekend_factor = 1.5 if date.dayofweek >= 5 else 1.0# 模擬季節性變化:夏季(6-8月)電子產品和食品銷量增加,冬季(11-2月)服裝和家居銷量增加seasonal_factor = 1.0if product in ['電子產品', '食品'] and date.month in [6, 7, 8]:seasonal_factor = 1.3elif product in ['服裝', '家居'] and date.month in [11, 12, 1, 2]:seasonal_factor = 1.4# 生成銷售量quantity = int(np.random.randint(10, 50) * weekend_factor * seasonal_factor)# 生成銷售額 (價格在100-500之間)price = np.random.randint(100, 500)amount = quantity * price# 添加到列表sales_data.append({'日期': date,'產品': product,'銷量': quantity,'單價': price,'銷售額': amount})# 創建DataFrame
sales_df = pd.DataFrame(sales_data)# 顯示數據樣本
print(sales_df.head())
print(f"數據集大小: {sales_df.shape}")
輸出結果:
2. 分組分析
# 按產品分組,計算總銷售額和平均銷售額
product_summary = sales_df.groupby('產品').agg({'銷售額': ['sum', 'mean'],'銷量': ['sum', 'mean']
})
print(product_summary)# 按月份和產品分組,計算每月每種產品的總銷售額
sales_df['月份'] = sales_df['日期'].dt.month
monthly_product_sales = sales_df.groupby(['月份', '產品'])['銷售額'].sum().unstack()
print(monthly_product_sales)
輸出結果:
3. 時間序列分析
# 將數據按日期和產品分組,計算每日每種產品的總銷售額
daily_product_sales = sales_df.groupby(['日期', '產品'])['銷售額'].sum().unstack()# 計算7天移動平均
moving_avg = daily_product_sales.rolling(window=7).mean()# 每月銷售額趨勢
monthly_sales = sales_df.groupby([sales_df['日期'].dt.to_period('M'), '產品'])['銷售額'].sum().unstack()
print(monthly_sales)
輸出結果:
4. 數據可視化
import matplotlib.pyplot as plt
import seaborn as sns# 設置中文顯示(防止中文注釋出錯,實際圖表無中文)
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False# 設置圖表風格
plt.style.use('seaborn-v0_8-darkgrid')
plt.figure(figsize=(14, 8))# 繪制每月產品銷售額趨勢(Monthly Sales Trend by Product)
monthly_sales.plot(kind='line', marker='o')
plt.title('Monthly Sales Trend by Product in 2023', fontsize=14)
plt.xlabel('Month', fontsize=12)
plt.ylabel('Sales Amount', fontsize=12)
plt.legend(title='Product Category')
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('monthly_sales_trend.png', dpi=300)
plt.show()# 繪制產品銷售額占比餅圖(Sales Proportion by Product)
plt.figure(figsize=(10, 8))
product_total = sales_df.groupby('產品')['銷售額'].sum()
plt.pie(product_total, labels=product_total.index, autopct='%1.1f%%', startangle=90, shadow=True, explode=[0.05, 0, 0, 0])
plt.title('Sales Proportion by Product', fontsize=14)
plt.axis('equal')
plt.savefig('product_sales_pie.png', dpi=300)
plt.show()# 繪制季節性變化熱力圖(Heatmap of Monthly Average Sales by Product)
plt.figure(figsize=(12, 8))
pivot_table = sales_df.pivot_table(index=sales_df['日期'].dt.month,columns='產品',values='銷售額',aggfunc='mean'
)
sns.heatmap(pivot_table, annot=True, fmt='.0f', cmap='YlGnBu')
plt.title('Heatmap of Monthly Average Sales by Product', fontsize=14)
plt.xlabel('Product Category', fontsize=12)
plt.ylabel('Month', fontsize=12)
plt.tight_layout()
plt.savefig('monthly_product_heatmap.png', dpi=300)
plt.show()
輸出結果:
六、總結與拓展
通過本文的學習,我們掌握了Pandas中的數據分組與聚合、排序與排名以及時間序列分析等高級數據分析技能。這些技能對于從數據中提取有價值的信息至關重要。
1. 關鍵知識點回顧
- 數據分組:使用
groupby()
按一個或多個列對數據進行分組 - 聚合函數:通過
sum()
、mean()
、count()
等函數對分組數據進行聚合計算 - 排序:使用
sort_values()
和sort_index()
對數據進行排序 - 排名:使用
rank()
對數據進行排名,支持多種處理并列情況的方法 - 時間序列處理:包括時間索引、重采樣、移動窗口等操作
2. 實際應用場景
- 銷售數據分析:按產品、地區、時間等維度分析銷售趨勢和模式
- 金融數據分析:股票價格時間序列分析,計算移動平均線和波動性
- 用戶行為分析:按用戶群體分組,分析不同群體的行為特征
- 傳感器數據處理:對高頻采集的傳感器數據進行降采樣和異常檢測
3. 學習資源推薦
- 官方文檔:Pandas官方文檔
- 書籍:《Python for Data Analysis》by Wes McKinney
- 在線課程:Coursera的"Data Analysis with Python"
練習題:
- 使用本文介紹的銷售數據,按產品和月份分組,計算銷售額最高的前3個產品-月份組合。
- 實現一個函數,對時間序列數據檢測異常值(比如超過3個標準差的值)。
- 嘗試使用groupby和transform計算每個產品的銷售額占該產品總銷售額的百分比。
希望這篇文章能幫助你更好地理解Pandas的高級數據分析功能。如有問題,歡迎在評論區留言,在下一篇文章中,星球之旅的第26天,我們將探索 Matplotlib 可視化,敬請期待!
創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder😊)
如果你對今天的內容有任何問題,或者想分享你的學習心得,歡迎在評論區留言討論!