Генерация дат на основе 2 разных диапазонов - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть фрейм данных df со столбцами:

Date_1  count
01/09/2019  5
02/09/2019  4
03/09/2019  5
04/09/2019  6
05/09/2019  7
06/09/2019  8
07/09/2019  10
08/09/2019  9
09/09/2019  11
10/09/2019  12
11/09/2019  13
12/09/2019  14
13/09/2019  15
14/09/2019  18
15/09/2019  17
16/09/2019  18
17/09/2019  19
18/09/2019  20
19/09/2019  21
20/09/2019  22
21/09/2019  23
22/09/2019  24
23/09/2019  25
24/09/2019  26
25/09/2019  27
26/09/2019  28
27/09/2019  29
28/09/2019  30
29/09/2019  30
30/09/2019  30

Я хочу сгенерировать df2, имеющий 3 столбца date_1, count, date_2, такой, чтобы:

date_2 генерировалось на основе count. если число для date_1 равно 5, то в кадре данных будет 5 записей. Кроме того, у date_2 есть ограничение:

  1. 70% значений находятся в диапазоне от (date_1 - 10 до date_1 - 2)
  2. остальные значения находятся в диапазоне (date_1- от 30 до date_1 - 11)

Также каждый из date_1 и date_2 должен быть уникальным кортежем, т.е. ни одна пара (date_1, date_2) не повторяется.

Например:

для первой строки: 4 значения для date_1 должны находиться в диапазоне range1 = (01/09/2019 - 10 = 22/08/2019 по 01/09/ 2019 - 30/08/2019) и значение остальных 1 должно находиться в диапазоне 2 (01/09/2019 - 30 = с 08/08/2019 по 09/09/2019 - 21/08/2019).

для значений в кадре данных, где count = 30, нам не нужно вносить это изменение, поскольку нам нужны уникальные значения, и поскольку общее значение, которое может принимать date_2, равно 30, мы должны включить все значения. (мы не можем пойти с 70% и 30% в этом сценарии)

Я не могу понять, как конкретно спроектировать этот массив данных на основе этих факторов. Таким образом, для количества> 11 он должен иметь все значения в диапазоне 1 (8 значений). до этого деление составляло 70% и 30% в диапазоне 1 и диапазоне 2.

Может кто-нибудь помочь мне в определении этих ограничений.

Спасибо

1 Ответ

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

Первая определяемая функция:

def getSample(rng, n):
    siz = rng.size
    return rng.sample(n = n, replace = n > siz)

Возвращает выборку из n элементов из rng . Если это возможно (требуемое количество элементов меньше или равно количеству элементов в rng ), выборка не повторяется.

Вторая функция:

def getDates(dat, n):
    td1d = pd.Timedelta(1, 'D')
    # Date ranges
    rng1 = pd.Series(pd.date_range(dat - td1d * 30, dat - td1d * 11, freq='D'))
    rng2 = pd.Series(pd.date_range(dat - td1d * 10, dat - td1d * 2, freq='D'))
    # Numbers of dates
    n2 = int(round(n * 0.7))
    n1 = n - n2
    return pd.concat([getSample(rng1, n1), getSample(rng2, n2)])\
        .sort_values().reset_index(drop=True)

It:

  • Генерирует оба диапазона дат [d-30: d-11] и [d-10: d-2] .
  • Вычисляет оба числа элементов для каждого диапазона.
  • Получает выборки из обоих диапазонов (требуемого размера), объединяет их, сортирует и возвращает результат.

И последняя функция, генерирующая «реплицированные строки» для текущей строки:

def repl(row):
    dat = row.Date_1
    cnt = row['count']
    return pd.DataFrame({'date_1': dat, 'count': cnt, 'date_2': getDates(dat, cnt)})

Теперь осталось применить эту функцию и объединить результаты:

df2 = pd.concat(df1.sort_values('Date_1').\
    apply(repl, axis=1).tolist(), ignore_index=True)

Примечание. В случаях, когда число дат из диапазона [d-10: d-2] превышает количество доступных дат, даты составляют с повторениями.

Редактировать следующий комментарий от 21: 48: 25Z

Ваша концепция не удалась: возьмите, например, строку для 2019-09-28 ( 3Требуется 0 строк). Из диапазона [d-10: d-2] следует взять 21 дату.

Но поскольку там только 9 дат , то:

  • мы можем взять только 9 из этого диапазона,
  • , поэтому оставшиеся 21 даты должны быть взяты из второго диапазона ( [d-30: d-11] ).

Но этот диапазон содержит только 20 дат, поэтому невозможно взять 21 даты изтам (без повторов).

Вывод: Ваши требования преувеличены.

Еще одно замечание:

На самом деле тот факт, что эта задача невозможна, можетможно увидеть из следующего наблюдения:

Диапазон дат [d-30: d-2] содержит 29 даты. Поэтому не ожидайте, что из этого пула могут быть взяты 30 различных дат , независимо от разделения между двумя поддиапазонами.

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