Случайное семя выбрало разные строки

Я применил .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 по индексу и печатаю, он дает разные результаты.

Можете ли вы поделиться частями вашего кода, пожалуйста?

markuscosinus 26.03.2019 16:04

Да, фрейм данных считывается и больше нигде не создается. У меня есть отпечатки форм df в качестве проверки по пути.

Jon 26.03.2019 16:14

Я не уверен, что понимаю. С помощью set_index я изменяю индекс, чтобы использовать столбец «id» в качестве значения. .sort_index должен сортироваться по идентификатору, верно? Проблема, с которой я сталкиваюсь, заключается в том, что .sample выбирает разные строки каждый раз, когда я повторно запускаю данные, в том числе извлекая их из источника. Ничего не меняется. Мой вопрос: использует ли образец не индекс, а какую-то другую меру для выбора строк на основе семени?

Jon 26.03.2019 16:28

В вашем примере единственным аргументом, который использует пример, является длина выборки df, random_state и n. Если они не изменятся, выбранные строки не изменятся, независимо от индекса. Поведение, которое вы обнаружите, не соответствует тому, как оно должно себя вести, и я не могу воспроизвести вашу проблему, поэтому, вероятно, это ошибка, не связанная с sample. Пожалуйста, предоставьте минимальный воспроизводимый пример пример данных, который воспроизводит проблему, и, вероятно, при попытке сделать это вы можете обнаружить проблему в своем коде. stackoverflow.com/questions/20109391/… показывает, как давать хорошие примеры с данными.

ALollz 26.03.2019 16:42

Проблема была решена другой стороной. Порядок считываемых данных менялся при каждом запуске, и сортировка по индексу перед выполнением выборки исправляла это. Вопрос был о том, как работает заполнение, связанное с .sample(), а не только о выборке аргументов. Изменение порядка повлияло на .sample(), и я предполагаю, что это то, как random_state выбирает строки, что было моим основным вопросом. Выбранные строки действительно изменились, несмотря на то, что аргументы .sample() не изменились, как я и спрашивал.

Jon 26.03.2019 16:59

Джон, мы никак не можем узнать, что вы заранее изменили порядок своих данных. Я по-прежнему придерживаюсь своей точки зрения, что эта проблема вызвана чем-то, кроме предоставленных вами данных, и что образец выбирает ту же самую строку (по индексу целочисленного массива), независимо от данных. Однако из-за изменения организации строк один и тот же индекс целочисленного массива выбирает разные данные.

ALollz 26.03.2019 17:08

Мой вопрос заключался в том, как работает random_state с семенем. Ответ с ним выбирает x-ю строку, а не по индексу, чтобы решить проблему. Я указал, где возникла проблема в контексте моего кода. Незнание того, как работает random_state, затрудняло предоставление полного контекста, поэтому это была основная часть моего вопроса, а проблема сортировки не была его частью.

Jon 26.03.2019 17:15
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
7
456
2

Ответы 2

Применение .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 26.03.2019 17:10

@Jon Да, образец основан на базовых индексах массива, как я показал. Это не имеет ничего общего с фактическим индексом DataFrame (что было бы проблематично, например, если бы он был дублирован). Поэтому, когда ваши данные не отсортированы последовательно, они по-прежнему выбирают одну и ту же строку по .iloc, но эта строка потенциально содержит другую информацию, чем предыдущая выборка.

ALollz 26.03.2019 17:18

Другие вопросы по теме