“在 Pandas 中,邏輯運算和比較運算是數據篩選的基礎工具。通過與(&)、或(|)等操作符,可以輕松實現復雜條件篩選,比如選出市盈率最大且市凈率最小的股票。”
1. 邏輯運算和比較
在 Pandas 中,DataFrame 的邏輯運算和比較是數據處理中常用的操作,主要用于篩選和過濾數據。以下是詳細說明和實現方法:
1.1. DataFrame 的邏輯運算
邏輯運算包括與(&)、或(|)、非(~)和異或(^),通常與比較運算結合使用。
示例代碼:
import pandas as pd
# 創建示例 DataFrame
df = pd.DataFrame({
'A': [True, False, True],
'B': [False, True, False]
})
# 與運算
print(df['A'] & df['B'])
# 或運算
print(df['A'] | df['B'])
# 非運算
print(~df['A'])
# 異或運算
print(df['A'] ^ df['B'])
輸出結果:
0 False
1 False
2 False
dtype: bool
0 True
1 True
2 True
dtype: bool
0 False
1 True
2 False
dtype: bool
0 True
1 True
2 True
dtype: bool
1.2. DataFrame 的比較運算
比較運算包括 >、<、==、!=、>=、<=,返回布爾值組成的 DataFrame 或 Series。
示例代碼:
# 創建示例 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 比較運算
print(df['A'] > 1) # 返回布爾 Series
print(df > 2) # 返回布爾 DataFrame
輸出結果:
0 False
1 True
2 True
Name: A, dtype: bool
A B
0 False True
1 False True
2 True True
Dataframe中包含了我們提取的特征。要選取PE最大同時是PB最小的前30列,怎么做?
假設 DataFrame 中包含以下特征:
- PE:市盈率
- PB:市凈率
import pandas as pd
# 創建示例 DataFrame
data = {
'PE': [10, 20, 30, 40, 50],
'PB': [1.5, 1.2, 1.0, 0.8, 0.5]
}
df = pd.DataFrame(data)
選取 PE 最大且 PB 最小的前 30 列, 要實現這一需求,可以按照以下步驟操作:
- 計算 PE 的最大值和 PB 的最小值。
- 根據條件篩選數據。
- 選取前 30 列。
# 篩選 PE 最大且 PB 最小的行
filtered_df = df[(df['PE'] == df['PE'].max()) & (df['PB'] == df['PB'].min())]
# 選取前 30 列(假設列數足夠)
result = filtered_df.iloc[:, :30]
print(result)
輸出結果:
PE PB
4 50 0.5
2. 分組運算(groupby)
在 Pandas 中,groupby 是用于對 DataFrame 進行分組運算的核心方法。它遵循“拆分-應用-合并”的邏輯,即先將數據按指定條件分組,然后對每個分組執行操作,最后將結果合并。以下是詳細說明和具體實現方法:
2.1. groupby 的基本語法
groupby 的基本語法為:
df.groupby(by=分組鍵)[選擇列].聚合函數
- ?by:指定分組的列名或列名列表。
- ?選擇列:可選,指定需要操作的列。
- ?聚合函數:如 sum()、mean()、max() 等。
示例:
import pandas as pd
# 創建示例 DataFrame
data = {'行業': ['科技', '科技', '金融', '金融', '科技'],
'公司': ['A', 'B', 'C', 'D', 'E'],
'PE': [30, 25, 15, 20, 35]}
df = pd.DataFrame(data)
# 按行業分組并計算平均 PE
result = df.groupby('行業')['PE'].mean()
print(result)
輸出結果:
行業
科技 30.0
金融 17.5
Name: PE, dtype: float64
2.2. groupby 的應用
假設你的因子分析數據表包含以下列:
- ?行業標簽:表示公司所屬的行業。
- ?PE值:表示公司的市盈率。
示例數據:
data = {'行業': ['科技', '科技', '金融', '金融', '科技', '金融'],
'公司': ['A', 'B', 'C', 'D', 'E', 'F'],
'PE': [30, 25, 15, 20, 35, 10]}
df = pd.DataFrame(data)
選出每個行業 PE 最強的 5 支, “PE 最強”可以理解為 PE 值最高的公司。以下是實現步驟:
- 按行業分組。
- 對每個分組按 PE 值降序排序。
- 選取每個分組的前 5 行。
# 按行業分組,并對每個分組按 PE 值降序排序
grouped = df.groupby('行業', group_keys=False)
# 選取每個行業 PE 值最高的 5 家公司
result = grouped.apply(lambda x: x.nlargest(5, 'PE'))
print(result)
輸出結果:
行業 公司 PE
0 科技 A 30
4 科技 E 35
1 科技 B 25
2 金融 C 15
3 金融 D 20
5 金融 F 10
3. 多重索引和高級索引
在 Pandas 中,DataFrame 的多重索引(MultiIndex)和高級索引是處理復雜數據結構的重要工具。它們允許你在一個軸上創建多個層級的索引,從而更靈活地組織和訪問數據。以下是詳細說明:
3.1. ?多重索引(MultiIndex)?
多重索引是指在一個軸上(行或列)擁有多個層級的索引。它適用于處理具有層次化結構的數據,例如按地區和時間分類的數據。
3.1.1. 創建多重索引
Pandas 提供了多種方法創建多重索引,以下是常見的方式:
[?從數組創建]
import pandas as pd
arrays = [['A', 'A', 'B', 'B'], [1, 2, 1, 2]]
multi_index = pd.MultiIndex.from_arrays(arrays, names=('Letter', 'Number'))
df = pd.DataFrame({'Value': [10, 20, 30, 40]}, index=multi_index)
print(df)
[從元組創建]
tuples = [('A', 1), ('A', 2), ('B', 1), ('B', 2)]
multi_index = pd.MultiIndex.from_tuples(tuples, names=('Letter', 'Number'))
df = pd.DataFrame({'Value': [10, 20, 30, 40]}, index=multi_index)
print(df)
[從笛卡爾積創建]
letters = ['A', 'B']
numbers = [1, 2]
multi_index = pd.MultiIndex.from_product([letters, numbers], names=('Letter', 'Number'))
df = pd.DataFrame({'Value': [10, 20, 30, 40]}, index=multi_index)
print(df)
3.1.2. ?訪問多重索引數據
使用 loc 訪問:
print(df.loc[('A', 1)]) # 訪問特定行
?使用 xs 交叉選擇:
print(df.xs(1, level='Number')) # 獲取第二層級索引為 1 的所有行
?使用切片器:
print(df.loc[pd.IndexSlice[:, 2], :]) # 獲取第二層級索引為 2 的所有行
3.1.3 ?操作多重索引
?交換層級:
df_swapped = df.swaplevel(0, 1)
print(df_swapped)
?重排序層級:
df_sorted = df.sort_index(level='Number')
print(df_sorted)
?重置索引:
df_reset = df.reset_index()
print(df_reset)
3.2. ?高級索引
高級索引是指在多重索引的基礎上,使用更靈活的方法選擇和操作數據。
3.2.1. ?使用 reindex 重新索引
reindex 可以根據指定的索引重新排列數據,并填充缺失值:
new_index = [('B', 2), ('A', 1), ('C', 3)]
df_reindexed = df.reindex(new_index)
print(df_reindexed)
3.2.2. ?使用 align 對齊索引
align 可以將兩個具有不同索引的 DataFrame 對齊:
df1 = pd.DataFrame({'Value': [10, 20]}, index=[('A', 1), ('B', 2)])
df2 = pd.DataFrame({'Value': [30, 40]}, index=[('B', 2), ('C', 3)])
aligned_df1, aligned_df2 = df1.align(df2)
print(aligned_df1)
print(aligned_df2)
!!! Notes
- 多重索引:通過 MultiIndex 創建多層級索引,支持靈活的數據組織和訪問。
- ?高級索引:通過 reindex、align、groupby 等方法實現復雜的數據操作。
通過熟練掌握多重索引和高級索引,可以更高效地處理和分析復雜數據。
4. 窗口函數
Pandas 中的窗口函數(Window Functions)是一種強大的工具,用于對數據進行滑動窗口計算。它們通常用于時間序列數據或有序數據,支持滾動計算、擴展計算和指數加權移動等操作。以下是 Pandas 中窗口函數的詳細說明。
4.1. ?窗口函數的基本概念
窗口函數是一種特殊的函數,它在一個固定大小的窗口內對數據進行計算,并返回與原始數據相同數量的結果。常見的窗口函數包括:
- ?滾動窗口(Rolling Window)?:在一個固定大小的窗口內對數據進行計算。
- ?擴展窗口(Expanding Window)?:從第一個數據點開始,逐步增加窗口大小,直到包含所有數據點。
- ?指數加權移動窗口(Exponentially Weighted Moving Window)?:對較近的數據賦予更高的權重,較遠的數據賦予較低的權重。
4.2. ?滾動窗口(Rolling Window)?
滾動窗口用于在固定大小的窗口內對數據進行計算。例如,計算過去 5 天的平均值或最大值。
import pandas as pd
# 創建示例 DataFrame
data = {'value': [1, 2, 3, 4, 5, 6, 7, 8, 9]}
df = pd.DataFrame(data)
# 計算滾動平均值,窗口大小為 3
df['rolling_mean'] = df['value'].rolling(window=3).mean()
print(df)
參數說明:
- ?window:窗口大小。
- ?min_periods:窗口中需要的最小數據點數量,否則結果為 NaN。
- ?center:是否以當前行為中心劃分窗口。
4.3. 擴展窗口(Expanding Window)?
擴展窗口從第一個數據點開始,逐步增加窗口大小,直到包含所有數據點。它通常用于計算累計和、累計平均等。
# 計算累計和
df['expanding_sum'] = df['value'].expanding().sum()
print(df)
4.4. 指數加權移動窗口(Exponentially Weighted Moving Window)?
指數加權移動窗口對較近的數據賦予更高的權重,較遠的數據賦予較低的權重。它在金融數據分析中非常有用。
# 計算指數加權移動平均
df['ewm_mean'] = df['value'].ewm(span=3).mean()
print(df)
參數說明:
- ?span:指定衰減系數。
- ?alpha:直接指定衰減因子。
!!! Notes
- 窗口大小的選擇:根據具體應用場景和數據特點選擇窗口大小,過小可能導致結果波動較大,過大可能掩蓋重要細節。
- ?邊界值處理:使用 min_periods 參數控制最小窗口大小,避免 NaN 值。
- 數據缺失處理:使用 fillna() 填充缺失值或 dropna() 刪除缺失值。
5. 數學運算和統計
在 Pandas 中,DataFrame 提供了豐富的數學運算和統計功能,能夠方便地對數據進行計算和分析。
5.1. ?數學運算
Pandas 支持對 DataFrame 進行基本的數學運算,包括加法、減法、乘法、除法等。這些運算可以逐元素進行,也可以對整列或整行進行操作。
示例代碼:
import pandas as pd
# 創建示例 DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)
# 加法
df['C'] = df['A'] + df['B']
# 減法
df['D'] = df['A'] - df['B']
# 乘法
df['E'] = df['A'] * df['B']
# 除法
df['F'] = df['A'] / df['B']
print(df)
輸出結果:
A B C D E F
0 1 4 5 -3 4 0.25
1 2 5 7 -3 10 0.40
2 3 6 9 -3 18 0.50
其他數學運算:
- ?冪運算:df['A'] ?** 2
- ?平方根:df['A'].pow(0.5)
- ?對數運算:df['A'].apply(np.log)(需導入 numpy 庫)
5.2. ?統計計算
Pandas 提供了多種統計方法,用于對 DataFrame 中的數據進行分析。
常用統計方法:
- ?求和:df.sum()
- ?平均值:df.mean()
- ?最大值:df.max()
- ?最小值:df.min()
- ?標準差:df.std()
- ?方差:df.var()
- ?中位數:df.median()
- ?眾數:df.mode()
- ?分位數:df.quantile(q=0.25)(計算 25% 分位數)
示例代碼:
# 計算各列的和
sum_result = df.sum()
# 計算各列的平均值
mean_result = df.mean()
# 計算各列的最大值
max_result = df.max()
# 計算各列的最小值
min_result = df.min()
# 計算各列的標準差
std_result = df.std()
# 計算描述性統計信息
desc_stats = df.describe()
print(desc_stats)
輸出結果:
A B C D E F
count 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
mean 2.000000 5.000000 7.000000 -3.000000 10.666667 0.383333
std 1.000000 1.000000 2.000000 0.000000 7.023796 0.125833
min 1.000000 4.000000 5.000000 -3.000000 4.000000 0.250000
25% 1.500000 4.500000 6.000000 -3.000000 7.000000 0.325000
50% 2.000000 5.000000 7.000000 -3.000000 10.000000 0.400000
75% 2.500000 5.500000 8.000000 -3.000000 14.000000 0.450000
max 3.000000 6.000000 9.000000 -3.000000 18.000000 0.500000
5.3. ?高級統計功能
Pandas 還支持更復雜的統計操作,例如:
- ?累計統計:df.cumsum()(累計和)、df.cummax()(累計最大值)
- ?相關性分析:df.corr()(計算相關系數矩陣)
- ?協方差分析:df.cov()(計算協方差矩陣)
- ?偏度和峰度:df.skew()(偏度)、df.kurtosis()(峰度)
示例代碼:
# 計算累計和
cumsum_result = df.cumsum()
# 計算相關系數矩陣
corr_matrix = df.corr()
# 計算協方差矩陣
cov_matrix = df.cov()
print(corr_matrix)
5.4. ?分組統計
Pandas 的 groupby 方法可以對數據進行分組,然后對每個分組進行統計計算。
示例代碼:
# 創建示例 DataFrame
data = {'Category': ['A', 'B', 'A', 'B', 'A'], 'Value': [10, 20, 30, 40, 50]}
df = pd.DataFrame(data)
# 按 Category 分組并計算每組的平均值
grouped_stats = df.groupby('Category').mean()
print(grouped_stats)
輸出結果:
Value
Category
A 30.0
B 30.0
浙公網安備 33010602011771號