Как я могу получить столбец со случайными выборками на основе весов, содержащихся в фрейме данных pandas?

#python #pandas

#python #pandas

Вопрос:

У меня есть фрейм данных с более чем миллионом строк. Для каждой строки у меня есть 4 столбца, содержащих веса. Как я могу эффективно выполнять выборку для каждой строки с соответствующими весами? Я просто хотел бы выбрать число 1,2,3 или 4 для каждой строки, используя веса каждой строки. Прямо сейчас у меня есть этот цикл for, но это займет слишком много времени.

 df = pd.DataFrame({
    '1': [0.155, 0.138, ...],
    '2': [0.473, 0.307, ...],
    '3': [0.291, 0.490, ...],
    '4': [0.080, 0.064, ...],
    'pick': ['']

})

for i in range(0, len(df)): 
    df['pick'][i] = random.choices([1,2,3,4], weights=[df['1'][i], df['2'][i], df['3'][i], df['4'][i]], k=1)
  

Ответ №1:

Попробуйте с помощью numpy, обычно это быстрее:

 for i in range(len(df)):
    df['pick'][i]=np.random.choice([1,2,3,4], 1, p=list(df.iloc[i,:4]))
  

Однако, поскольку ваши веса не всегда прибавляются к 1, измените некоторый столбец (например, 4-й) таким образом, прежде чем:

 df['4']=1-(df['1'] df['2'] df['3'])
  

Вывод:

        1      2      3      4  pick
0  0.155  0.473  0.291  0.081     2
1  0.138  0.307  0.490  0.065     4
  

Ответ №2:

Чтобы добавить к предыдущему ответу:

Вы могли бы использовать функцию apply вместо итерации по всем строкам (что обычно происходит медленнее).

Сначала определите (лямбда) функцию, затем примените функцию к каждой строке:

 pick_function = lambda row_vals : np.random.choice([1,2,3,4], p=row_vals)

df['pick'] = df.apply(pick_function,axis=1) # axis=1 -> passes the row's values as the argument
  

Кроме того, функция lambda выполняет то же самое, что и эта:

 def pick_function(row_vals):
    rand_value = np.random.choice([1,2,3,4], p=row_vals)
    return rand_value