Я применил .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 должен сортироваться по идентификатору, верно? Проблема, с которой я сталкиваюсь, заключается в том, что .sample выбирает разные строки каждый раз, когда я повторно запускаю данные, в том числе извлекая их из источника. Ничего не меняется. Мой вопрос: использует ли образец не индекс, а какую-то другую меру для выбора строк на основе семени?
В вашем примере единственным аргументом, который использует пример, является длина выборки df, random_state и n. Если они не изменятся, выбранные строки не изменятся, независимо от индекса. Поведение, которое вы обнаружите, не соответствует тому, как оно должно себя вести, и я не могу воспроизвести вашу проблему, поэтому, вероятно, это ошибка, не связанная с sample. Пожалуйста, предоставьте минимальный воспроизводимый пример пример данных, который воспроизводит проблему, и, вероятно, при попытке сделать это вы можете обнаружить проблему в своем коде. stackoverflow.com/questions/20109391/… показывает, как давать хорошие примеры с данными.
Проблема была решена другой стороной. Порядок считываемых данных менялся при каждом запуске, и сортировка по индексу перед выполнением выборки исправляла это. Вопрос был о том, как работает заполнение, связанное с .sample(), а не только о выборке аргументов. Изменение порядка повлияло на .sample(), и я предполагаю, что это то, как random_state выбирает строки, что было моим основным вопросом. Выбранные строки действительно изменились, несмотря на то, что аргументы .sample() не изменились, как я и спрашивал.
Джон, мы никак не можем узнать, что вы заранее изменили порядок своих данных. Я по-прежнему придерживаюсь своей точки зрения, что эта проблема вызвана чем-то, кроме предоставленных вами данных, и что образец выбирает ту же самую строку (по индексу целочисленного массива), независимо от данных. Однако из-за изменения организации строк один и тот же индекс целочисленного массива выбирает разные данные.
Мой вопрос заключался в том, как работает random_state с семенем. Ответ с ним выбирает x-ю строку, а не по индексу, чтобы решить проблему. Я указал, где возникла проблема в контексте моего кода. Незнание того, как работает random_state, затрудняло предоставление полного контекста, поэтому это была основная часть моего вопроса, а проблема сортировки не была его частью.






Применение .sort_index() после чтения данных и перед выполнением .sample() устранило проблему. Пока данные остаются неизменными, каждый раз будет производиться одна и та же выборка.
При выборке строк (без веса) важны только 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, но эта строка потенциально содержит другую информацию, чем предыдущая выборка.
Можете ли вы поделиться частями вашего кода, пожалуйста?