Первая определяемая функция:
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 различных дат , независимо от разделения между двумя поддиапазонами.