本文目录导读:

我来介绍几种使用Pandas进行数据分组洗牌的方法。
方法1:使用groupby和sample
import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
'group': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C'],
'value': [1, 2, 3, 4, 5, 6, 7, 8]
})
print("原始数据:")
print(df)
# 方法1:在每个组内随机洗牌
def shuffle_group(group):
return group.sample(frac=1, random_state=42)
shuffled_df = df.groupby('group', group_keys=False).apply(shuffle_group)
print("\n分组内洗牌结果:")
print(shuffled_df)
方法2:使用groupby和sample保持组结构
# 保持组内结构,只打乱组顺序
def shuffle_groups(df, group_col):
"""打乱组的顺序,但保持组内数据不变"""
# 获取唯一组列表
unique_groups = df[group_col].unique()
# 随机打乱组顺序
shuffled_groups = np.random.permutation(unique_groups)
# 创建新的DataFrame
result = pd.concat([df[df[group_col] == g] for g in shuffled_groups], ignore_index=True)
return result
# 示例
df_shuffled_groups = shuffle_groups(df, 'group')
print("组顺序打乱结果:")
print(df_shuffled_groups)
方法3:加权随机洗牌
# 基于权重的组内洗牌
def weighted_shuffle(group, weight_col=None):
"""基于权重进行组内洗牌"""
if weight_col:
weights = group[weight_col]
return group.sample(frac=1, weights=weights)
return group.sample(frac=1)
# 创建带权重的数据
df_weight = pd.DataFrame({
'group': ['A', 'A', 'A', 'B', 'B', 'B'],
'value': [1, 2, 3, 4, 5, 6],
'weight': [0.1, 0.2, 0.7, 0.3, 0.3, 0.4]
})
# 按权重洗牌
weighted_shuffled = df_weight.groupby('group', group_keys=False).apply(
lambda x: weighted_shuffle(x, 'weight')
)
print("\n加权洗牌结果:")
print(weighted_shuffled)
方法4:保持行数平衡的分组洗牌
def balanced_group_shuffle(df, group_col, seed=None):
"""均衡的分组洗牌,确保每个组有相似的样本数"""
if seed is not None:
np.random.seed(seed)
result_dfs = []
groups = df.groupby(group_col)
# 找到最小组的样本数
min_size = groups.size().min()
for name, group in groups:
# 从每个组中随机选择相同数量的样本
sampled = group.sample(n=min_size, random_state=seed)
result_dfs.append(sampled)
return pd.concat(result_dfs, ignore_index=True)
# 创建不均衡的数据
df_imbalanced = pd.DataFrame({
'group': ['A', 'A', 'A', 'A', 'B', 'B', 'C', 'C', 'C'],
'value': [1, 2, 3, 4, 5, 6, 7, 8, 9]
})
balanced = balanced_group_shuffle(df_imbalanced, 'group', seed=42)
print("\n均衡洗牌结果:")
print(balanced)
方法5:交叉验证的分组洗牌
def group_kfold_split(df, group_col, n_folds=5, shuffle=True, random_state=None):
"""分组K折交叉验证的数据分割"""
from sklearn.model_selection import GroupKFold
groups = df[group_col]
gkf = GroupKFold(n_splits=n_folds)
folds = []
for train_idx, test_idx in gkf.split(df, groups=groups):
train_df = df.iloc[train_idx]
test_df = df.iloc[test_idx]
folds.append((train_df, test_df))
return folds
# 使用示例
df_large = pd.DataFrame({
'group': ['A']*10 + ['B']*10 + ['C']*10,
'feature1': np.random.randn(30),
'feature2': np.random.randn(30),
'target': np.random.randint(0, 2, 30)
})
folds = group_kfold_split(df_large, 'group', n_folds=3)
print("\n分组K折交叉验证:")
for i, (train, test) in enumerate(folds):
print(f"Fold {i+1}: 训练集 {len(train)} 样本, 测试集 {len(test)} 样本")
print(f"训练集分组: {train['group'].unique()}")
print(f"测试集分组: {test['group'].unique()}")
实际应用示例
# 销售数据的分组分析
def analyze_sales_shuffle(sales_df):
"""对销售数据进行分组洗牌分析"""
# 按地区分组洗牌
shuffled_by_region = sales_df.groupby('region', group_keys=False).apply(
lambda x: x.sample(frac=1)
)
# 计算洗牌前后的统计
original_stats = sales_df.groupby('region')['sales'].agg(['mean', 'std'])
shuffled_stats = shuffled_by_region.groupby('region')['sales'].agg(['mean', 'std'])
# 比较差异
comparison = pd.DataFrame({
'原始均值': original_stats['mean'],
'洗牌后均值': shuffled_stats['mean'],
'差异': original_stats['mean'] - shuffled_stats['mean']
})
return comparison
# 示例数据
sales_data = pd.DataFrame({
'region': ['North']*5 + ['South']*5 + ['East']*5,
'product': ['A', 'B', 'C', 'D', 'E']*3,
'sales': [100, 150, 200, 120, 180, 90, 130, 160, 110, 140, 80, 120, 170, 95, 155]
})
result = analyze_sales_shuffle(sales_data)
print("\n销售数据分析结果:")
print(result)
这些方法可以根据你的具体需求选择使用:
- 方法1:组内完全随机化
- 方法2:保持组结构,只打乱顺序
- 方法3:带权重的随机化
- 方法4:均衡采样
- 方法5:交叉验证分割
选择哪种方法取决于你的具体应用场景和数据分析需求。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播