随机抽样Pandas中数据帧的子集

WGP*_*WGP 24 python sample random-sample pandas

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

我如何采取100个部分中只有一部分的50个随机样本.数据集已经被排序,前1000个结果是下一个部分的第一个部分,依此类推.

非常感谢

And*_*den 33

您可以使用sample方法*:

In [11]: df = pd.DataFrame([[1, 2], [3, 4], [5, 6], [7, 8]], columns=["A", "B"])

In [12]: df.sample(2)
Out[12]:
   A  B
0  1  2
2  5  6

In [13]: df.sample(2)
Out[13]:
   A  B
3  7  8
0  1  2
Run Code Online (Sandbox Code Playgroud)

*在其中一个DataFrames上.

注意:如果您的样本量较大,那么DataFrame的大小会引发错误,除非您使用替换进行采样.

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
Run Code Online (Sandbox Code Playgroud)

  • @hoang tran replace表示是否进行替换采样。如果没有替换手段,一旦选择了一条线,就无法再次选择它(例如,我从袋子中取出大理石,并且不要放回去,因此无法再次绘制)。使用替换意味着我可以再次对同一条线进行采样(例如,在绘制大理石后,我将其放回包中,然后再绘制下一个大理石,这样我可以再次获得同一条线)。 (4认同)
  • 您能解释一下“替换”的作用吗?该文档对我来说还不清楚。谢谢! (2认同)

jpj*_*ade 8

一种解决方案是使用choicenumpy中的函数。

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

import numpy as np
chosen_idx = np.random.choice(1000, replace=False, size=50)
df_trimmed = df.iloc[chosen_idx]
Run Code Online (Sandbox Code Playgroud)

当然,这不考虑您的块结构。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]
Run Code Online (Sandbox Code Playgroud)


Jef*_*eff 8

您可以"section"向数据添加一列,然后执行分组和示例:

import numpy as np
import pandas as pd

df = pd.DataFrame(
    {"x": np.arange(1_000 * 100), "section": np.repeat(np.arange(100), 1_000)}
)
# >>> df
#            x  section
# 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 rows x 2 columns]

sample = df.groupby("section").sample(50)
# >>> sample
#            x  section
# 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 rows x 2 columns]
Run Code Online (Sandbox Code Playgroud)

.query("section == 42")如果您只对特定部分感兴趣,则可以添加其他内容或其他内容。

请注意,这需要 pandas 1.1.0,请参阅此处的文档: https: //pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.sample.html

对于旧版本,请参阅@msh5678的答案