【问题标题】:Random Seed Chose Different Rows随机种子选择不同的行
【发布时间】:2019-08-17 00:36:53
【问题描述】:

我正在应用 .sample 并将 random_state 设置为常量,在使用 set_index 之后它开始选择不同的行。先前包含在子集中的已删除成员。我不确定播种如何选择行。这有意义还是出了什么问题?

这是做了什么:

df.set_index('id',inplace=True, verify_integrity=True)

df_small_F = df.loc[df['gender']=='F'].apply(lambda x: x.sample(n=30000, random_state=47))

df_small_M = df.loc[df['gender']=='M'].apply(lambda x: x.sample(n=30000, random_state=46))

df_small=pd.concat([df_small_F,df_small_M],verify_integrity=True)

当我按索引对 df_small 进行排序并打印时,它会产生不同的结果。

【问题讨论】:

  • 你能分享你的部分代码吗?
  • 是的,数据框正在被读取,而不是在其他任何地方创建。我有 df 形状的打印件作为检查。
  • 我不确定我是否理解。使用 set_index 我将索引更改为使用“id”列作为值。 .sort_index 应该按“id”排序吧?我遇到的问题是 .sample 每次我重新运行数据时都会选择不同的行,包括从源中提取数据。什么都没有改变。我的问题是,样本是否不使用索引,而是使用其他一些措施来根据种子选择行?
  • 在您的示例中,示例使用的唯一参数是采样的 dfrandom_staten 的长度。如果那些没有改变,它选择的行将不会改变,无论索引如何。您发现的行为不是它应有的行为方式,我无法重现您的问题,因此可能存在与 sample 无关的错误。请向minimal reproducible example 提供重现问题的示例数据,并且在尝试这样做时,您可能会在代码中发现问题。 stackoverflow.com/questions/20109391/… 展示了如何用数据给出好的例子。
  • 问题已由另一方解决。每次运行时读取的数据的顺序都会发生变化,并在执行采样修复之前按索引对其进行排序。问题是关于播种如何与 .sample() 相关,而不仅仅是采样参数。更改影响 .sample() 的排序,我认为它是 random_state 选择行的方式,这是我的主要问题。它选择的行确实发生了变化,尽管 .sample() 的参数没有改变,就像我问的那样。

标签: python python-3.x pandas random-seed


【解决方案1】:

在对行进行抽样(无权重)时,唯一重要的是n、行数以及是否选择替换。无论数据如何,这都会生成要采用的 .iloc 索引。

对于行,采样发生为;

axis_length = self.shape[0]  # DataFrame length

rs = pd.core.common.random_state(random_state)  
locs = rs.choice(axis_length, size=n, replace=replace, p=weights)  # np.random_choice
return self.take(locs, axis=axis, is_copy=False)

只是为了说明问题

样本数据

import pandas as pd
import numpy as np

n = 100000
np.random.seed(123)
df = pd.DataFrame({'id': list(range(n)), 'gender': np.random.choice(['M', 'F'], n)})
df1 = pd.DataFrame({'id': list(range(n)), 'gender': ['M']}, 
                    index=np.random.choice(['foo', 'bar', np.NaN], n)).assign(blah=1)

采样将始终选择行 42083(整数数组索引):df.iloc[42803] 用于此种子和长度:

df.sample(n=1, random_state=123)
#          id gender
#42083  42083      M

df1.sample(n=1, random_state=123)
#        id gender  blah
#foo  42083      M     1

df1.reset_index().shift(10).sample(n=1, random_state=123)
#      index       id gender  blah
#42083   nan  42073.0      M   1.0

即使是 numpy:

np.random.seed(123)
np.random.choice(df.shape[0], size=1, replace=False)
#array([42083])

【讨论】:

  • 随机种子采样也取决于顺序。就像你说的,它总是会选择第 42083 行。这就是我的问题所在。读入时数据的顺序发生了变化,因此第 42083 行发生了变化。排序解决了这个问题。我不确定 random_state 播种在上下文中是如何工作的。
  • @Jon 是的,该示例基于我展示的基础数组索引。它与实际的 DataFrame 索引无关(例如,如果它被复制就会有问题)。因此,当您的数据未始终如一地排序时,它仍会按 .iloc 对同一行进行采样,但该行的信息可能与先前的样本不同。
【解决方案2】:

在读入数据后和执行 .sample() 之前应用 .sort_index() 可以纠正问题。只要数据保持不变,每次都会产生相同的样本。

【讨论】:

    猜你喜欢
    • 2013-03-27
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多