常见用的数据转换分类:

  1. 提取日期中的年、月、周、星期几
  2. 将字符串分类变量编码为哑变量(One-Hot Encoding)
  3. 计算订单总金额(单价×数量)
  4. 计算折扣率(实际支付价 / 原价)
  5. 构造用户购买频次特征
  6. 转换时间戳为可排序的时间序列
  7. 构造商品销量排名字段
  8. 合并多个数据源生成宽表
  9. 对价格进行标准化(Z-score)
  10. 构造是否参与促销的布尔标签

我们将展示如何进行这些常见的数据转换任务。假设我们有一个包含销售订单数据的DataFrame,并逐步应用这些转换操作。

首先,让我们创建一个示例DataFrame来模拟原始数据:

import pandas as pd
import numpy as np

# 创建示例DataFrame
data = {
    'order_id': [1, 2, 3, 4, 5, 6, 7, 8],
    'product_id': ['A001', 'B002', 'D004', 'E005', 'F006', 'G007', 'H008', 'I009'],
    'category_code': ['C1', 'C2', 'C1', 'C3', 'C4', 'C5', 'C6', 'C7'],
    'amount': [100.00, 200.00, 300.00, 400.00, 500.00, 600.00, 700.00, 800.00],
    'original_price': [120.00, 220.00, 320.00, 420.00, 520.00, 620.00, 720.00, 820.00],
    'quantity': [1, 2, 1, 1, 2, 1, 1, 2],
    'order_date': ['2025-06-01', '2025-06-02', '2025-06-03', '2025-06-04', '2025-06-05', '2025-06-06', '2025-06-07', '2025-06-08'],
    'customer_id': [101, 102, 103, 104, 105, 106, 107, 108],
    'promotion': [False, True, False, True, False, True, False, True]
}

df = pd.DataFrame(data)
print("原始数据:")
print(df)

接下来,我们将逐个处理上述提到的数据转换任务。

1. 提取日期中的年、月、周、星期几

# 转换order_date为日期格式
df['order_date'] = pd.to_datetime(df['order_date'])

# 提取年、月、周、星期几
df['year'] = df['order_date'].dt.year
df['month'] = df['order_date'].dt.month
df['week_of_year'] = df['order_date'].dt.isocalendar().week.astype(int)
df['day_of_week'] = df['order_date'].dt.dayofweek

print("\n提取日期中的年、月、周、星期几后:")
print(df)

2. 将字符串分类变量编码为哑变量(One-Hot Encoding)

# 将category_code进行one-hot encoding
df_encoded = pd.get_dummies(df, columns=['category_code'], prefix='cat')

print("\n将字符串分类变量编码为哑变量后:")
print(df_encoded)

3. 计算订单总金额(单价×数量)

# 计算订单总金额
df_encoded['total_amount'] = df_encoded['amount'] * df_encoded['quantity']

print("\n计算订单总金额后:")
print(df_encoded)

4. 计算折扣率(实际支付价 / 原价)

# 计算折扣率
df_encoded['discount_rate'] = (df_encoded['amount'] / df_encoded['original_price']).round(2)

print("\n计算折扣率后:")
print(df_encoded)

5. 构造用户购买频次特征

假设我们有一个客户购买记录的DataFrame,用于构造用户购买频次特征。

# 创建客户购买记录的DataFrame
purchase_history = {
    'customer_id': [101, 102, 103, 104, 105, 106, 107, 108, 101, 102, 103, 104],
    'purchase_count': [2, 3, 1, 2, 1, 3, 2, 1, 1, 2, 1, 3]
}
df_purchase_history = pd.DataFrame(purchase_history)

# 合并客户购买记录
df_transformed = pd.merge(df_encoded, df_purchase_history, on='customer_id', how='left')

print("\n构造用户购买频次特征后:")
print(df_transformed)

6. 转换时间戳为可排序的时间序列

在我们的例子中,order_date已经是日期时间格式,可以直接排序。

# 确保order_date是datetime类型
df_transformed['order_date'] = pd.to_datetime(df_transformed['order_date'])

# 按order_date排序
df_sorted = df_transformed.sort_values(by='order_date')

print("\n按order_date排序后:")
print(df_sorted)

7. 构造商品销量排名字段

假设我们有一个商品销量统计的DataFrame,用于构造商品销量排名特征。

# 创建商品销量统计的DataFrame
product_sales = {
    'product_id': ['A001', 'B002', 'D004', 'E005', 'F006', 'G007', 'H008', 'I009'],
    'sales_rank': [1, 2, 3, 4, 5, 6, 7, 8]
}
df_product_sales = pd.DataFrame(product_sales)

# 合并商品销量统计
df_final = pd.merge(df_sorted, df_product_sales, on='product_id', how='left')

print("\n构造商品销量排名字段后:")
print(df_final)

8. 对价格进行标准化(Z-score)

from scipy.stats import zscore

# 对amount列进行z-score标准化
df_final['amount_zscore'] = zscore(df_final['amount'])

print("\n对价格进行标准化后:")
print(df_final)

9. 构造是否参与促销的布尔标签

# 构造是否参与促销的布尔标签
df_final['is_promotion'] = df_final['promotion'].astype(bool)

print("\n构造是否参与促销的布尔标签后:")
print(df_final)

综合以上步骤,最终的转换后的DataFrame如下:

这段代码展示了从原始数据到经过全面转换的数据的过程。你可以根据实际需求调整每一步的操作。

import pandas as pd
import numpy as np
from scipy.stats import zscore

# 创建示例DataFrame
data = {
    'order_id': [1, 2, 3, 4, 5, 6, 7, 8],
    'product_id': ['A001', 'B002', 'D004', 'E005', 'F006', 'G007', 'H008', 'I009'],
    'category_code': ['C1', 'C2', 'C1', 'C3', 'C4', 'C5', 'C6', 'C7'],
    'amount': [100.00, 200.00, 300.00, 400.00, 500.00, 600.00, 700.00, 800.00],
    'original_price': [120.00, 220.00, 320.00, 420.00, 520.00, 620.00, 720.00, 820.00],
    'quantity': [1, 2, 1, 1, 2, 1, 1, 2],
    'order_date': ['2025-06-01', '2025-06-02', '2025-06-03', '2025-06-04', '2025-06-05', '2025-06-06', '2025-06-07', '2025-06-08'],
    'customer_id': [101, 102, 103, 104, 105, 106, 107, 108],
    'promotion': [False, True, False, True, False, True, False, True]
}

df = pd.DataFrame(data)

# 转换order_date为日期格式
df['order_date'] = pd.to_datetime(df['order_date'])

# 提取年、月、周、星期几
df['year'] = df['order_date'].dt.year
df['month'] = df['order_date'].dt.month
df['week_of_year'] = df['order_date'].dt.isocalendar().week.astype(int)
df['day_of_week'] = df['order_date'].dt.dayofweek

# 将category_code进行one-hot encoding
df_encoded = pd.get_dummies(df, columns=['category_code'], prefix='cat')

# 计算订单总金额
df_encoded['total_amount'] = df_encoded['amount'] * df_encoded['quantity']

# 计算折扣率
df_encoded['discount_rate'] = (df_encoded['amount'] / df_encoded['original_price']).round(2)

# 创建客户购买记录的DataFrame
purchase_history = {
    'customer_id': [101, 102, 103, 104, 105, 106, 107, 108, 101, 102, 103, 104],
    'purchase_count': [2, 3, 1, 2, 1, 3, 2, 1, 1, 2, 1, 3]
}
df_purchase_history = pd.DataFrame(purchase_history)

# 合并客户购买记录
df_transformed = pd.merge(df_encoded, df_purchase_history, on='customer_id', how='left')

# 确保order_date是datetime类型
df_transformed['order_date'] = pd.to_datetime(df_transformed['order_date'])

# 按order_date排序
df_sorted = df_transformed.sort_values(by='order_date')

# 创建商品销量统计的DataFrame
product_sales = {
    'product_id': ['A001', 'B002', 'D004', 'E005', 'F006', 'G007', 'H008', 'I009'],
    'sales_rank': [1, 2, 3, 4, 5, 6, 7, 8]
}
df_product_sales = pd.DataFrame(product_sales)

# 合并商品销量统计
df_final = pd.merge(df_sorted, df_product_sales, on='product_id', how='left')

# 对amount列进行z-score标准化
df_final['amount_zscore'] = zscore(df_final['amount'])

# 构造是否参与促销的布尔标签
df_final['is_promotion'] = df_final['promotion'].astype(bool)

print("最终转换后的数据:")
print(df_final)