为什么df.sample和df.apply在这种情况下的工作方式不同?

时间:2018-06-12 09:27:51

标签: python python-3.x pandas

假设我有一个想要采样的数据帧

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(0,10,size=(100,2)),columns=list('AB'))

如果我们有

s = df.sample(5)
print(s)

我们得到一个长度为5的框架,它向我建议它是随机抽样的索引,然后返回每一行。

但是,如果我跑

 t = df.apply(lambda x: x.sample(5))
 print(t)

我得到一个长度为10的帧,每列被采样5次,并且数据帧在没有相关样本的单元格中返回NaN。为什么这两个函数的行为不同?我希望它们是一样的吗?

似乎df.sample(5)等同于

 df.apply(lambda x: np.random.choice(x,5))

现在如果我对数据帧进行分组。

g = df.groupby('A')

然后g.apply(lambda x: x.sample(2))给了我想要的东西(每组随机抽样2个),但应用与之前相同的等价

 g.apply(lambda x: np.random.choice(x,2))

给我一​​个ValueError。这是为什么?

1 个答案:

答案 0 :(得分:2)

默认情况下,

.sample会在被调用时使用随机种子(如果没有指定,则使用随机种子)。

当您执行df.sample(5)时,您将根据单个种子获取5个随机行。但是,当您执行t = df.apply(lambda x: x.sample(5))时,会为每个.sample调用生成一个新种子(例如,每列不同的一个),结果将是N行,表示采样的唯一索引的数量(在你的例子中可能是10但可能更少)。

您可以通过指定要采样的random_state参数来强制所有调用使用相同的随机序列,例如:

df.apply(lambda x: x.sample(5, random_state=42))

这给了你:

    A  B
83  8  3
53  7  3
70  7  2
45  3  8
44  1  1

df.sample(5, random_state=42)给你的内容相同。