根据2个不同的范围生成日期

时间:2019-11-04 13:41:17

标签: python pandas numpy

我有一个带有列的数据框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

我想生成具有3列date_1,count,date_2的df2,例如:

date_2是基于计数生成的。如果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)。

例如:

第一行: date_1的4个值应在范围1 =(01/09/2019-10 = 22/08/2019到01/09/2019-30/08/2019)范围内,其余1个值应在范围范围内2(01/09/2019-30 = 02/08/2019至01/09/2019-21/08/2019)。

对于count = 30的数据帧中的值,我们不需要进行此更改,因为我们需要唯一的值,并且由于date_2可以取的总值为30,因此我们必须合并所有值。 (在这种情况下,我们不能使用70%和30%)

我无法理解如何根据这些因素特别设计该数据框。因此,对于count> 11,它的所有值都应在1(8个值)范围内。在此之前,其范围1和范围2分别为70%和30%。

任何人都可以帮助我定义这些约束。

谢谢

1 个答案:

答案 0 :(得分:0)

要定义的第一个函数是:

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

它从 rng 返回 n 个元素的样本。 如果可能(所需的元素数量小于或等于 到 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)

它:

  • 同时生成两个日期范围 [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 的行(需要 30 行)。 在 [d-10:d-2] 范围内,应该取21个日期。

但是因为那里只有 9个日期,所以:

  • 我们只能从该范围内获取 9
  • 因此剩余的 21 日期应从第二个范围中获取 ( [d-30:d-11] )。

但是该范围仅包含 20 个日期,因此无法提取 21 从那里开始(无重复)。

结论:您的要求过高了。

再说一遍:

实际上可以从以下形式看出这一任务是不可能的 以下观察结果:

日期范围 [d-30:d-2] 包含 29 个日期。 因此,不要期望可以从该池中获取 30个不同的日期,而不管两个子范围之间的划分。