【问题标题】:Random Sample of a subset of a dataframe in PandasPandas 中数据帧子集的随机样本
【发布时间】:2016-10-31 07:58:18
【问题描述】:

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

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

非常感谢

【问题讨论】:

  • df.iloc[np.random.randint(1,1000,50),:]df1 是 100 个部分之一。

标签: python pandas sample random-sample


【解决方案1】:

您可以在数据中添加"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]

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

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

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

【讨论】:

    【解决方案2】:

    谢谢你,杰夫, 但是我收到了一个错误;

    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))
    

    【讨论】:

    【解决方案3】:

    这是递归的好地方。

    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()
    

    output: [6, 0, 7, 1, 3, 5, 4, 2]

    【讨论】:

      【解决方案4】:

      你可以使用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
      

      *在 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
      

      【讨论】:

      • 你能解释一下replace是做什么的吗?我不清楚文档。谢谢!
      • @hoang 它需要一个“带替换的样本”,所以如果你有一个大小为 5 的数据集,你可以取一个大小为 10 的样本。另外,如果你取 N 个元素的样本,没有样本大小为 N 的元素将包含所有元素,替换后可能不会。例如。见statisticshowto.datasciencecentral.com/…
      • @hoang tran replace 表示是否进行替换采样。没有替换意味着一旦选择了一条线,就不能再选择它了(例如,我从袋子里拉出一个弹珠,但没有放回去,所以我不能再画了)。替换意味着我可以再次对同一条线进行采样(例如,在绘制了一个弹珠之后,我将它放回袋子中,然后再绘制下一个弹珠,这样我就可以再次获得相同的弹珠)。
      • @goryh 直到什么时候发生?我的意思是,如果您在一定次数的迭代中重复此操作,您最终应该得到一个空数据框,对吧?
      • @whynote pandas.dataframe.sample() 实际上并没有改变数据框。我的大理石解释是关于有或没有替换的采样通常意味着 panadas 如何实现它。
      【解决方案5】:

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

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

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

      这当然没有考虑你的块结构。例如,如果您想要来自块 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]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-05-21
        • 1970-01-01
        • 2014-09-15
        相关资源
        最近更新 更多