Pandas数据框向量化抽样

4

我有一个简单的数据框,需要生成一个透视表:

    d = {'one' : ['A', 'B', 'B', 'C', 'C', 'C'], 'two' : [6., 5., 4., 3., 2., 1.],     'three' : [6., 5., 4., 3., 2., 1.], 'four' : [6., 5., 4., 3., 2., 1.]}
    df = pd.DataFrame(d)
    pivot = pd.pivot_table(df,index=['one','two'])

我想从结果透视对象的'one'列中的每个不同元素随机抽样1行。(在此示例中,'A'将始终被抽样,而'B'和'C'有更多的选项。)我刚开始使用pandas 0.18.0版本,并且知道.sample方法。我尝试使用类似以下代码的.groupby方法应用抽样函数:

    grouped = pivot.groupby('one').apply(lambda x: x.sample(n=1, replace=False))

我在尝试对这个主题进行变化时引发了KeyError错误,所以我认为现在是时候给这个看似简单的问题带来新的视角了...

谢谢任何帮助!

1个回答

3

由于'one'不是pivot中的列名而是索引名,因此会引发KeyError错误:

In [11]: pivot
Out[11]:
         four  three
one two
A   6.0   6.0    6.0
B   4.0   4.0    4.0
    5.0   5.0    5.0
C   1.0   1.0    1.0
    2.0   2.0    2.0
    3.0   3.0    3.0

你需要使用level参数:
In [12]: pivot.groupby(level='one').apply(lambda x: x.sample(n=1, replace=False))
Out[12]:
             four  three
one one two
A   A   6.0   6.0    6.0
B   B   4.0   4.0    4.0
C   C   1.0   1.0    1.0

由于索引重复,这并不完全正确!使用 as_index=False 稍微好一些:

In [13]: pivot.groupby(level='one', as_index=False).apply(lambda x: x.sample(n=1))
Out[13]:
           four  three
  one two
0 A   6.0   6.0    6.0
1 B   4.0   4.0    4.0
2 C   2.0   2.0    2.0

注意:每次都会随机选择一行。
作为一种替代方案,还有一个潜在的更高效的变体(它会提取子框架)。
In [21]: df.iloc[[np.random.choice(x) for x in g.indices.values()]]
Out[21]:
   four one  three  two
1   5.0   B    5.0  5.0
3   3.0   C    3.0  3.0
0   6.0   A    6.0  6.0

令人印象深刻的海登先生。令人印象深刻。 :) - tdunham28

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接