Генерация диапазона уникальных случайных чисел для каждой группы в pandas - PullRequest
0 голосов
/ 18 июня 2020

Мне нужно создать диапазон уникальных случайных чисел от 0 до 99999 для каждой группы. У меня есть следующий набор данных

District    Prefix  Quota       
A           98426   783
A           98427   223
A           98446   127
A           98626   51
B           98049   167
B           98079   153
B           98140   120
B           98159   139
B           98169   182
B           98249   86
B           98426   588
B           98446   96
C           98049   104
C           98060   68
C           98149   65
C           98150   68
C           98159   86
C           98160   80
C           98169   113

Код для воспроизведения:

import pandas as pd
df = pd.DataFrame([
    ['A', 98426, 783],
    ['A', 98427, 223],
    ['A', 98446, 127],
    ['A', 98626, 51],
    ['B', 98049, 167],
    ['B', 98079, 153],
    ['B', 98140, 120],
    ['B', 98159, 139],
    ['B', 98169, 182],
    ['B', 98249, 86],
    ['B', 98426, 588],
    ['B', 98446, 96],
    ['C', 98049, 104],
    ['C', 98060, 68],
    ['C', 98149, 65],
    ['C', 98150, 68],
    ['C', 98159, 86],
    ['C', 98160, 80],
    ['C', 98169, 113]
], 
    columns=['District', 'Prefix', 'Quota'])

, поэтому мне нужно сгенерировать «квоту» уникального номера от 0 до 99999 и добавить его в префикс, чтобы я мог создать номер 10 di git.

Я пробовал:

numbers = np.random.choice(range(99999), size=df.Quota.sum(), replace=False)
random = df.Prefix.repeat(df.Quota)*100000 + numbers

, но проблема в том, что он подсчитывает «Квоту» и генерирует уникальные числа от 0 до 99999. но я хочу уникальный номер от 0 до 99999 доступен для каждого префикса. например. предположим, что np.random.choice (range (99999), size = df.Quota.sum (), replace = False) сгенерировал 16195 и добавил к первому префиксу «98426». тот же номер не будет сгенерирован, и он не будет доступен для другого префикса. поэтому диапазон (0-99999) должен быть уникальным для каждого префикса

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Вот решение с использованием transform, random.choice и explode.

def make_random_numbers(x):
    total = x.sum()
    r = np.random.choice(range(99999), total, replace = False)
    chunks = x.cumsum()[:-1]
    res =  np.hsplit(r, chunks)  
    return res

df["rand_items"] = df.groupby("Prefix")["Quota"].transform(make_random_numbers)
df.explode("rand_items")

Результат:

  District  Prefix  Quota rand_items
0        A   98426    783       2681
0        A   98426    783      94952
0        A   98426    783      79496
0        A   98426    783      58361
0        A   98426    783      54883
0        A   98426    783      44819
0        A   98426    783      36209
0        A   98426    783      91710
...
18        C   98169    113      41859
18        C   98169    113      92311
18        C   98169    113      18572
18        C   98169    113      72492
18        C   98169    113      39188
18        C   98169    113      36808
18        C   98169    113      32055
18        C   98169    113      74678
0 голосов
/ 18 июня 2020

Этот метод возвращает список случайных вариантов для каждой строки:

def gen_rand(x):
    return (x['Prefix'].min() * 1E5 + np.random.choice(range(99999),
        size=sum(x['Quota']), replace = False)).astype(int)
df.groupby('Prefix').apply(gen_rand)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...