如何根据每个类的频率对pandas数据帧进行二次采样?

时间:2017-04-26 17:32:58

标签: python python-3.x pandas

如何通过考虑每个标签或类别的频率对熊猫数据帧进行二次采样。例如,考虑以下dataset的类频率:

Class              freq
Iris-setosa        50
Iris-versicolor    50
Iris-virginica     50

frequency for each class

如何为每个班级随机抽取50%的实例,以减少我的数据集?我已经准备好知道我能做到:

df['class'].sample(frac=0.5)

或:

df.take(np.random.permutation(len(df))[:5])

但是,这不符合数据集的类频率。任何想法如何得到:

Class              freq
Iris-setosa        25
Iris-versicolor    25
Iris-virginica     25

1 个答案:

答案 0 :(得分:3)

在“课程”列上执行groupby,然后使用sample

df.groupby('Class').apply(pd.DataFrame.sample, frac=0.5).reset_index(drop=True)

上述解决方案将摆脱您现有的索引值。如果要保留原始索引值,请使用reset_index(level='Class', drop=True)

在一些示例数据上显示:

# Setup fake data.
np.random.seed([3, 1415])
df = pd.DataFrame({
    'Class': list('AAAABBBBCC'),
    'Value1': np.random.randint(10, size=10),
    'Value2': np.random.random(10)})

其中给出了以下初始DataFrame:

  Class  Value1    Value2
0     A       0  0.018571
1     A       2  0.182415
2     A       7  0.332961
3     A       3  0.150202
4     B       8  0.810506
5     B       7  0.716278
6     B       0  0.191527
7     B       6  0.097532
8     C       8  0.374224
9     C       6  0.215276

然后使用上述解决方案:

# Creating a new index.
df.groupby('Class').apply(pd.DataFrame.sample, frac=0.5).reset_index(drop=True)

  Class  Value1    Value2
0     A       0  0.018571
1     A       7  0.332961
2     B       0  0.191527
3     B       6  0.097532
4     C       6  0.215276


# Maintaining the existing index.
df.groupby('Class').apply(pd.DataFrame.sample, frac=0.5).reset_index(level='Class', drop=True)

  Class  Value1    Value2
0     A       0  0.018571
2     A       7  0.332961
6     B       0  0.191527
7     B       6  0.097532
9     C       6  0.215276