Python 熊猫中数据帧子集的随机样本

Python 熊猫中数据帧子集的随机样本,python,pandas,sample,random-sample,Python,Pandas,Sample,Random Sample,假设我有一个包含100000个条目的数据框,并希望将其拆分为包含1000个条目的100个部分 我如何从100个部分中的一个部分随机抽取50个样本。数据集已经排序,因此前1000个结果是第一部分、下一部分、下一部分,依此类推 非常感谢一个解决方案是使用numpy的选项功能 假设您想要100个条目中的50个,您可以使用: import numpy as np chosen_idx = np.random.choice(1000, replace=False, size=50) df_trimmed

假设我有一个包含100000个条目的数据框,并希望将其拆分为包含1000个条目的100个部分

我如何从100个部分中的一个部分随机抽取50个样本。数据集已经排序,因此前1000个结果是第一部分、下一部分、下一部分,依此类推


非常感谢

一个解决方案是使用numpy的
选项
功能

假设您想要100个条目中的50个,您可以使用:

import numpy as np
chosen_idx = np.random.choice(1000, replace=False, size=50)
df_trimmed = df.iloc[chosen_idx]
这当然不是考虑你的区块结构。例如,如果您想从block
i
中获得50项样本,可以执行以下操作:

import numpy as np
block_start_idx = 1000 * i
chosen_idx = np.random.choice(1000, replace=False, size=50)
df_trimmed_from_block_i = df.iloc[block_start_idx + chosen_idx]
您可以使用以下方法*:

*在其中一个节数据帧上

注意:如果您的样本大小大于数据帧的大小,这将引发错误,除非您使用替换样本

In [14]: df.sample(5)
ValueError: Cannot take a larger sample than population when 'replace=False'

In [15]: df.sample(5, replace=True)
Out[15]:
   A  B
0  1  2
1  3  4
2  5  6
3  7  8
1  3  4

这是递归的好地方

def main2():
    rows = 8  # say you have 8 rows, real data will need len(rows) for int
    rands = []
    for i in range(rows):
        gen = fun(rands)
        rands.append(gen)
    print(rands)  # now range through random values


def fun(rands):
    gen = np.random.randint(0, 8)
    if gen in rands:
        a = fun(rands)
        return a
    else: return gen


if __name__ == "__main__":
    main2()
输出:[6,0,7,1,3,5,4,2]
您可以在数据中添加一个
“节”
列,然后执行分组方式和示例:

将numpy导入为np
作为pd进口熊猫
df=pd.DataFrame(
{“x”:np.arange(1_000*100),“section”:np.repeat(np.arange(100),1_000)}
)
#>>>df
#x剖面
# 0          0        0
# 1          1        0
# 2          2        0
# 3          3        0
# 4          4        0
# ...      ...      ...
# 99995  99995       99
# 99996  99996       99
# 99997  99997       99
# 99998  99998       99
# 99999  99999       99
#
#[100000行x 2列]
样本=df.groupby(“部分”)。样本(50)
#>>>样本
#x剖面
# 907      907        0
# 494      494        0
# 775      775        0
# 20        20        0
# 230      230        0
# ...      ...      ...
# 99740  99740       99
# 99272  99272       99
# 99863  99863       99
# 99198  99198       99
# 99555  99555       99
#
#[5000行x 2列]
如果您只对某个特定部分感兴趣,可以使用附加的
.query(“section==42”)
或其他任何内容

注:这需要pandas 1.1.0,请参见此处的文档:

对于旧版本,请参见@msh5678的答案谢谢你,杰夫, 但我收到了一个错误

AttributeError: Cannot access callable attribute 'sample' of 'DataFrameGroupBy' objects, try using the 'apply' method
因此,我建议使用以下命令代替
sample=df.groupby(“section”).sample(50)

df.groupby('section').apply(lambda grp: grp.sample(50))

df.iloc[np.random.randint(11000,50),:]
df1
是100个部分中的一个。您能解释一下
replace
的作用吗?文件我不清楚。谢谢大家!@hoang它需要一个“替换样本”,所以如果你有一个大小为5的数据集,你可以选择一个大小为10的样本。此外,如果您对N个元素进行采样,如果没有大小为N的样本,则每个元素都将具有,但替换后可能不会。例如,参见@hoang tran replace是指是否进行样品更换。不替换意味着一旦拾取了一条线,就不能再拾取它(例如,我从袋子中拉出一个大理石,不把它放回袋子中,所以我不能再绘制它)。替换意味着我可以再次对同一条线进行采样(例如,在绘制一个大理石之后,我会在绘制下一个大理石之前将其放回袋子中,以便我可以再次获得相同的一个)。@goryh直到何时发生这种情况?我的意思是,如果在一定次数的迭代中重复此操作,您应该会得到一个空的数据帧,对吗?@whynote.dataframe.sample()实际上不会更改数据帧。我的解释是关于带替换或不带替换的采样通常意味着什么,而不是panadas是如何实现它的。groupby示例刚刚添加到pandas 1.1.0中,请参见此处的文档:。谢谢你指出,我会更新我的答案。
df.groupby('section').apply(lambda grp: grp.sample(50))