Разверните набор данных на основе значений столбца - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть кадр данных df1:

Date_1     Date_2       i_count c_book
01/09/2019  02/08/2019  2       204
01/09/2019  03/08/2019  2       211
01/09/2019  04/08/2019  2       218
01/09/2019  05/08/2019  2       226
01/09/2019  06/08/2019  2       234
01/09/2019  07/08/2019  2       242
01/09/2019  08/08/2019  2       251
01/09/2019  09/08/2019  2       259
01/09/2019  10/08/2019  3       269
01/09/2019  11/08/2019  3       278
01/09/2019  12/08/2019  3       288
01/09/2019  13/08/2019  3       298
01/09/2019  14/08/2019  3       308
01/09/2019  15/08/2019  3       319
01/09/2019  16/08/2019  4       330
01/09/2019  17/08/2019  4       342
01/09/2019  18/08/2019  4       354
01/09/2019  19/08/2019  4       366
01/09/2019  20/08/2019  4       379
01/09/2019  21/08/2019  5       392
01/09/2019  22/08/2019  5       406
01/09/2019  23/08/2019  6       420
01/09/2019  24/08/2019  6       435
01/09/2019  25/08/2019  7       450
01/09/2019  26/08/2019  8       466
01/09/2019  27/08/2019  9       483
01/09/2019  28/08/2019  10      500
01/09/2019  29/08/2019  11      517
01/09/2019  30/08/2019  12      535
01/09/2019  31/08/2019  14      554

Я хочу расширить набор данных на основе i_count. i_count - количество строк, подлежащих репликации. так скажем, если i_count = 2 подразумевает, что 2 строки должны быть реплицированы для одного и того же.

Кроме того, я хочу создать новый столбец c_book_i, такой, чтобы c_book был разделен на записи в наборе данных. например, если i_count = 2, означает, что новый фрейм данных должен иметь 2 записи, а c_book_i должен иметь 2 записи, например sum(c_book_i) = c_book. Последнее ограничение заключается в том, что я хочу иметь c_book_i > 10 во всех случаях.

пока:

def f(x):
    i = np.random.random(len(x))
    j = i/sum(i) * x
    return j

joined_df2 = df1.reindex(df1.index.repeat(df1['i_count']))
joined_df2['c_book_i'] = joined_df2.groupby(['Date_1','Date_2'])['c_book'].transform(f)

Это дает мне то же самое, но без проверки того, что c_book должен быть больше 10. Есть много значений, получающихся меньше 10.

Может кто-нибудь помочь с тем же.

Спасибо

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

На основе решения

def f(x):
    total = x.iloc[0].astype(int)
    minimum = 10
    dividers = sorted(random.sample(range(minimum, total-minimum, minimum), len(x) - 1))
    return [a - b for a, b in zip(dividers + [total], [0] + dividers)]

Как это работает. Пусть итоговое значение равно 12, и мы хотим разделить его на 4 части с минимумом 2. Мы получаем диапазон от 2 до 12-2 с шагом 2 => [2,4,6,8,10]. Затем возьмите любые 3 числа, например, 2,4,8 и добавьте границы, поэтому [0,2,4,8,12]. Теперь различия между элементами этого списка [2,2,4,4] получат сумму 12 (разность между границами), и любой из них не может быть меньше 2

0 голосов
/ 08 ноября 2019

А как насчет:

def distribute_randomly(array):

    # This is the minimum to give each:
    minimum = 10

    # This means we have to reserve this amount:
    min_value_sum = len(array)*minimum

    # The rest we can distribute:
    to_distribute = array.sum() - min_value_sum

    # Get random values that all sum up to 1:
    random_values = numpy.random.rand(len(array))
    random_values = random_values/random_values.sum()

    # Return the minimum + a part of what is left to distribute
    return random_values*to_distribute + minimum

# Expand rows based on length of i_count:
df1 = df1.join(df1['i_count'].apply(lambda x: range(x)).explode().rename('dummy'))

# transform cbook_ to randomize
df1['c_book_2'] = df1.groupby('i_count')['c_book'].transform(distribute_randomly)

# Finally make sure they are not below 10:
df1['c_book_i'] = df1['c_book_2'].where(df1['c_book_2']>10, 10)

# If needed:
df1 = df1.reset_index()

Редактировать: Добавлена ​​«случайная» функция распределения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...