Python案例如何用Pandas做数据变换函数

wen python案例 1

本文目录导读:

Python案例如何用Pandas做数据变换函数

  1. 基础数据变换函数
  2. 数值变换函数
  3. 类别数据变换
  4. 时间序列变换
  5. 高级变换技巧
  6. 实用案例:数据清洗变换

我来详细介绍Pandas中常用的数据变换函数和方法。

基础数据变换函数

1 apply() - 对行或列应用函数

import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50],
    'C': ['a', 'b', 'c', 'd', 'e']
})
# 对列应用函数
df['A_squared'] = df['A'].apply(lambda x: x ** 2)
# 对多列应用函数
df['sum_AB'] = df[['A', 'B']].apply(lambda x: x['A'] + x['B'], axis=1)
# 对整个DataFrame应用函数
df_transformed = df.apply(lambda x: x * 2 if x.name in ['A', 'B'] else x)
print(df_transformed)

2 map() - 对Series进行映射

# 创建映射字典
grade_map = {'a': '优秀', 'b': '良好', 'c': '及格', 'd': '不及格', 'e': '缺考'}
# 应用映射
df['C_mapped'] = df['C'].map(grade_map)
print(df[['C', 'C_mapped']])

数值变换函数

1 标准化和归一化

from sklearn.preprocessing import StandardScaler, MinMaxScaler
# 创建数据
data = pd.DataFrame({
    'feature1': [1, 2, 3, 4, 5],
    'feature2': [100, 200, 300, 400, 500]
})
# Z-score标准化
def standardize(df, columns):
    scaler = StandardScaler()
    df[columns] = scaler.fit_transform(df[columns])
    return df
# Min-Max归一化
def normalize(df, columns):
    scaler = MinMaxScaler()
    df[columns] = scaler.fit_transform(df[columns])
    return df
# 自定义标准化函数
def custom_normalize(series):
    """自定义归一化函数"""
    return (series - series.min()) / (series.max() - series.min())
# 应用标准化
data['feature1_normalized'] = custom_normalize(data['feature1'])
print(data)

2 数学变换

# 创建数据
data = pd.DataFrame({'value': [1, 2, 3, 4, 5, 10, 100]})
# 对数变换
data['log_value'] = np.log(data['value'])
data['log10_value'] = np.log10(data['value'])
# 指数变换
data['exp_value'] = np.exp(data['value'])
# 平方根变换
data['sqrt_value'] = np.sqrt(data['value'])
# Box-Cox变换 (需要正值)
from scipy import stats
data['boxcox_value'], _ = stats.boxcox(data['value'] + 1)  # 加1避免0值
print(data)

类别数据变换

1 独热编码

# 创建类别数据
df = pd.DataFrame({
    'color': ['red', 'blue', 'green', 'red', 'blue'],
    'size': ['S', 'M', 'L', 'M', 'S'],
    'price': [100, 150, 200, 120, 130]
})
# 使用get_dummies进行独热编码
def one_hot_encode(df, columns):
    """对指定列进行独热编码"""
    return pd.get_dummies(df, columns=columns, prefix=columns)
# 应用独热编码
df_encoded = one_hot_encode(df, ['color', 'size'])
print(df_encoded)

2 标签编码

from sklearn.preprocessing import LabelEncoder
def label_encode(df, columns):
    """对指定列进行标签编码"""
    df_encoded = df.copy()
    le = LabelEncoder()
    for col in columns:
        df_encoded[col + '_encoded'] = le.fit_transform(df[col])
    return df_encoded
# 应用标签编码
df_labeled = label_encode(df, ['color', 'size'])
print(df_labeled)

时间序列变换

# 创建时间序列数据
dates = pd.date_range('2023-01-01', periods=100, freq='D')
ts_data = pd.DataFrame({
    'date': dates,
    'value': np.random.randn(100).cumsum()
})
def time_series_transform(df, date_col='date', value_col='value'):
    """时间序列常用变换"""
    df_transformed = df.copy()
    # 提取日期特征
    df_transformed['year'] = df[date_col].dt.year
    df_transformed['month'] = df[date_col].dt.month
    df_transformed['day'] = df[date_col].dt.day
    df_transformed['dayofweek'] = df[date_col].dt.dayofweek
    df_transformed['quarter'] = df[date_col].dt.quarter
    # 滚动统计
    df_transformed['rolling_mean_7'] = df[value_col].rolling(window=7).mean()
    df_transformed['rolling_std_7'] = df[value_col].rolling(window=7).std()
    # 差分
    df_transformed['diff_1'] = df[value_col].diff(1)
    # 累积和
    df_transformed['cumsum'] = df[value_col].cumsum()
    return df_transformed
# 应用时间序列变换
ts_transformed = time_series_transform(ts_data)
print(ts_transformed.head(10))

高级变换技巧

1 使用transform()方法

# 创建分组数据
df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C', 'C'],
    'value': [1, 2, 3, 4, 5, 6]
})
# 分组变换
df['group_mean'] = df.groupby('group')['value'].transform('mean')
df['group_rank'] = df.groupby('group')['value'].transform('rank')
df['group_std'] = df.groupby('group')['value'].transform('std')
print(df)

2 自定义变换管道

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, FunctionTransformer
# 自定义变换函数
def custom_transform(data):
    """自定义数据变换管道"""
    transformed = data.copy()
    # 添加交互特征
    if 'A' in transformed.columns and 'B' in transformed.columns:
        transformed['A_B_interaction'] = transformed['A'] * transformed['B']
    # 添加多项式特征
    for col in ['A', 'B']:
        if col in transformed.columns:
            transformed[col + '_squared'] = transformed[col] ** 2
    return transformed
# 创建变换管道
transform_pipeline = Pipeline([
    ('custom_transform', FunctionTransformer(custom_transform)),
    ('scaler', StandardScaler())
])
# 应用管道
df_example = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50]
})
result = transform_pipeline.fit_transform(df_example)
print(pd.DataFrame(result))

实用案例:数据清洗变换

def comprehensive_data_transform(df):
    """综合数据变换函数"""
    df_transformed = df.copy()
    # 处理缺失值
    for col in df_transformed.columns:
        if df_transformed[col].dtype in ['int64', 'float64']:
            df_transformed[col].fillna(df_transformed[col].median(), inplace=True)
        else:
            df_transformed[col].fillna('Unknown', inplace=True)
    # 处理异常值
    for col in df_transformed.select_dtypes(include=[np.number]).columns:
        Q1 = df_transformed[col].quantile(0.25)
        Q3 = df_transformed[col].quantile(0.75)
        IQR = Q3 - Q1
        lower_bound = Q1 - 1.5 * IQR
        upper_bound = Q3 + 1.5 * IQR
        # 截断异常值
        df_transformed[col] = df_transformed[col].clip(lower_bound, upper_bound)
    # 标准化数值列
    numeric_cols = df_transformed.select_dtypes(include=[np.number]).columns
    for col in numeric_cols:
        df_transformed[col + '_scaled'] = (df_transformed[col] - df_transformed[col].mean()) / df_transformed[col].std()
    return df_transformed
# 测试综合变换函数
test_data = pd.DataFrame({
    'numeric1': [1, 2, np.nan, 4, 100],  # 包含异常值
    'numeric2': [10, 20, 30, np.nan, 50],
    'category': ['A', 'B', None, 'A', 'C']
})
transformed_data = comprehensive_data_transform(test_data)
print(transformed_data)

这些案例涵盖了Pandas中大部分常用的数据变换技术,根据具体需求,你可以组合使用这些函数来实现复杂的数据预处理任务。

抱歉,评论功能暂时关闭!