У меня есть фрейм данных pandas, скажем, df, который выглядит как
Region ID
A 111
A 222
A 333
A 444
B 555
B 666
B 777
C 888
C 999
Столбец ID имеет свои веса. В этом случае вес A равен 2, вес B равен 2 и вес C равен 1.
веса никогда не превышают количество значений в столбце «Регион», что означает, что вес A никогда не превышает 4, поскольку у нас есть 4 записи для A.
Я хочу создать новый столбец и в этом столбце назначить случайные целочисленные значения в соответствии с весами в столбце ID, НО эти случайные значения должны быть распределены поровну. Для большей ясности я ожидаю, что новый фрейм данных должен выглядеть так
Region ID Random_Value
A 111 1
A 222 2
A 333 1
A 444 2
B 555 2
B 666 2
B 777 1
C 888 1
C 999 1
Когда значения в столбце «Регион» нечетные, например «B», я хочу присвоить случайные значения одинаково, но остаток может иметь любое случайное целочисленное значение.
Когда значения в столбце «Регион» четные, например «A», а его вес равен 2, мне нужно присвоить случайное целочисленное значение от 1 до 2 включительно и количество этих случайных целых чисел должно быть равным.
Я пробовал много способов, но безуспешно. Есть ли способ решить эту проблему?
Мой код следующий:
df['Random_Value'] = np.nan
A = df['region'] == 'A'
df.loc[A, 'Random_Value'] = np.random.randint(1,3, size=A.sum())
У вас есть колонка веса по каждому региону?
в настоящее время у меня нет, но я смогу добавить столбец веса в основной фрейм данных для каждого региона
Если вес A равен 2, это означает, что случайные значения должны быть только [1, 2]
верно?
Да, верно. Если вес равен 3, случайные значения должны быть [1,2,3]
Помимо попытки сгенерировать случайное число, вы можете сделать это, создав необходимый список случайных значений и попытавшись случайным образом выбрать индекс.
например:-
>>> a=[1,1,2,2]
>>> numpy.random.choice(4, 4, replace=False)
array([0, 3, 2, 1])
В соответствии с сгенерированным случайным индексом вы можете присвоить значения.
Для нечетных чисел вы можете создать случайный список следующим образом.
>>> np.random.randint(1,3,size=3)
array([1, 1, 2])
Предположим, у вас есть словарь, в котором хранится вес каждого региона.
weight_dict = {'A':2, 'B':2, 'C':1}
Я использовал.
groupy
, затем выполните цикл, чтобы получить каждую группу из dataframe
.np.range
, чтобы сгенерировать возможный вес из weight_dict
.np.repeat
для генерации случайных значений.np.random.choice
с replace=False
, чтобы получить значение без замены.Затем создайте новый столбец с np.concatenate
, чтобы объединить список.
ls = []
for idx, d in df.groupby('Region'):
group_size = d.shape[0]
weight_range = np.arange(1, weight_dict[idx]+1)
combination = np.repeat(weight_range, np.ceil(group_size/len(weight_range)))
ls.append(np.random.choice(combination, group_size, replace=False))
df['Random_Value'] = np.concatenate(ls)
df
Region ID Random_Value
0 A 111 2
1 A 222 1
2 A 333 1
3 A 444 2
4 B 555 1
5 B 666 2
6 B 777 2
7 C 888 1
8 C 999 1
Вы можете попробовать print
каждую переменную, чтобы увидеть, что произошло в цикле.
не могли бы вы отредактировать свой пост, чтобы включить код, который вы пробовали?