
本文详细介绍了如何利用pandas库,通过计算每列的中位数绝对离差(mad),从大型数据框中高效筛选出具有最高变异性的指定数量的列。mad作为一种稳健的离散度度量,特别适用于处理含有异常值的数据,本教程将提供具体的代码实现和步骤解析。
在数据分析和特征工程中,我们经常需要从包含大量特征(列)的数据集中识别出最具信息量或变异性的特征。当数据集规模庞大,例如包含数万列时,手动检查或基于简单统计量(如标准差)进行筛选可能效率低下或不够稳健。本文将重点介绍如何使用中位数绝对离差(Median Absolute Deviation, MAD)这一稳健的统计量,结合Pandas库的功能,高效地从DataFrame中选择具有最高MAD值的列。
中位数绝对离差(MAD)是衡量数据离散程度的一种稳健统计量。与标准差(Standard Deviation)不同,MAD对异常值不敏感,因为它基于中位数而不是均值。其计算步骤如下:
MAD的数学表达式为:$MAD = \text{median}(|X_i - \text{median}(X)|)$。当数据中存在异常值时,MAD能更准确地反映数据的集中趋势和离散程度,因为它不会被极端值过度拉伸。
假设我们有一个大型的Pandas DataFrame,其中包含大量的列(例如20,000列),每列都包含数值数据。我们的目标是从中选出MAD值最高的N列,生成一个新的DataFrame。以下是实现这一目标的具体步骤和相应的Python代码。
首先,我们创建一个模拟的DataFrame,以演示整个过程。这个DataFrame将有1000行和20000列,每列包含0到1之间的随机数。
import pandas as pd
import numpy as np
# 为了结果可复现,设置随机种子
rng = np.random.default_rng(seed=2024)
# 创建一个1000行,20000列的DataFrame
df = pd.DataFrame(rng.random((1000, 20000)))
print("原始DataFrame的形状:", df.shape)
print("原始DataFrame的前5行:\n", df.head())输出示例:
原始DataFrame的形状: (1000, 20000)
原始DataFrame的前5行:
0 1 2 3 ... 19996 19997 19998 19999
0 0.675831 0.214323 0.309452 0.799466 ... 0.876652 0.417957 0.302618 0.033723
1 0.165503 0.609271 0.840614 0.850995 ... 0.691652 0.327852 0.802473 0.680307
2 0.072913 0.244916 0.382106 0.403751 ... 0.310791 0.631182 0.103423 0.449572
3 0.430460 0.434423 0.130567 0.626203 ... 0.192436 0.017470 0.723502 0.482124
4 0.841660 0.838981 0.018308 0.298541 ... 0.347722 0.914452 0.551496 0.559643
[5 rows x 20000 columns]接下来,我们将计算DataFrame中每一列的MAD值。Pandas并没有直接提供df.mad()方法(尽管可以自定义)。我们可以根据MAD的定义手动实现。
# 1. 计算每列的中位数
column_medians = df.median()
# 2. 计算每列中每个值与其对应列中位数的绝对差值
# df.sub(column_medians) 会将df的每一列减去对应列的中位数
# .abs() 计算绝对值
absolute_deviations = df.sub(column_medians).abs()
# 3. 计算这些绝对差值的中位数,即得到每列的MAD
mad_values = absolute_deviations.median()
print("\nMAD值的前10个:\n", mad_values.head(10))mad_values现在是一个Pandas Series,其索引是原始DataFrame的列名,值是对应列的MAD。
现在我们有了每列的MAD值,下一步是根据这些值进行降序排序,并选择前N个列的索引。假设我们要选择MAD最高的1000列。
# 将MAD值按降序排序
sorted_mad = mad_values.sort_values(ascending=False)
# 选择MAD值最高的1000列的索引(列名)
# 如果需要选择不同的数量,只需修改head()中的参数
top_n_cols_indices = sorted_mad.head(1000).index
print(f"\nMAD最高的1000列的索引(前10个示例):\n {top_n_cols_indices[:10]}")最后一步是使用筛选出的列索引,从原始DataFrame中选择这些列,从而创建新的DataFrame。
# 使用筛选出的列索引构建新的DataFrame
df_selected_by_mad = df[top_n_cols_indices]
print(f"\n新DataFrame的形状: {df_selected_by_mad.shape}")
print("新DataFrame的前5行:\n", df_selected_by_mad.head())输出示例:
新DataFrame的形状: (1000, 1000)
新DataFrame的前5行:
4482 7833 10371 3059 ... 3509 1381 16339 13624
0 0.402850 0.343102 0.031398 0.512106 ... 0.243998 0.545462 0.607359 0.045264
1 0.166466 0.421302 0.763680 0.470844 ... 0.974354 0.719405 0.063957 0.206610
2 0.110333 0.384587 0.605379 0.700797 ... 0.440506 0.080930 0.795212 0.739654
3 0.796290 0.111921 0.006973 0.032487 ... 0.635054 0.084994 0.880535 0.953851
4 0.292507 0.397712 0.077202 0.344962 ... 0.096461 0.541819 0.640090 0.328734
[5 rows x 1000 columns]将上述步骤整合,可以得到一个简洁高效的函数:
import pandas as pd
import numpy as np
def select_top_n_cols_by_mad(dataframe: pd.DataFrame, n_cols: int) -> pd.DataFrame:
"""
根据中位数绝对离差(MAD)从DataFrame中选择变异性最高的N列。
参数:
dataframe (pd.DataFrame): 原始DataFrame。
n_cols (int): 希望选择的列的数量。
返回:
pd.DataFrame: 包含MAD值最高的N列的新DataFrame。
"""
if not isinstance(dataframe, pd.DataFrame):
raise TypeError("输入必须是Pandas DataFrame。")
if not isinstance(n_cols, int) or n_cols <= 0:
raise ValueError("n_cols 必须是正整数。")
if n_cols > dataframe.shape[1]:
print(f"警告: 请求的列数 {n_cols} 大于DataFrame的总列数 {dataframe.shape[1]},将返回所有列。")
return dataframe.copy()
# 计算每列的MAD
# df.sub(df.median()) 计算每个元素与所在列中位数的差值
# .abs() 取绝对值
# .median() 计算这些绝对差值的中位数,即为MAD
mad_values = dataframe.sub(dataframe.median()).abs().median()
# 将MAD值按降序排序,并获取前N个列的索引
top_n_cols_indices = mad_values.sort_values(ascending=False).head(n_cols).index
# 根据索引选择列,构建新的DataFrame
df_selected = dataframe[top_n_cols_indices]
return df_selected
# 最小工作示例 (Minimal Working Example)
if __name__ == "__main__":
# 创建一个包含20000列和1000行的随机DataFrame
rng = np.random.default_rng(seed=2024)
df_large = pd.DataFrame(rng.random((1000, 20000)))
print("原始DataFrame的形状:", df_large.shape)
# 选择MAD最高的1000列
selected_df = select_top_n_cols_by_mad(df_large, 1000)
print("\n根据MAD选择后的DataFrame形状:", selected_df.shape)
print("根据MAD选择后的DataFrame前5行:\n", selected_df.head())
# 尝试选择超过总列数的列
selected_all_df = select_top_n_cols_by_mad(df_large, 25000)
print("\n尝试选择超过总列数的DataFrame形状:", selected_all_df.shape)通过上述方法,我们可以有效地利用Pandas和中位数绝对离差,从大规模数据集中筛选出最具变异性的特征,为后续的数据分析和模型构建提供更精炼、更稳健的数据基础。
以上就是使用Pandas根据中位数绝对离差(MAD)选择DataFrame高变异性列的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号