我有一个带有列的数据框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具有以下约束:
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%。
任何人都可以帮助我定义这些约束。
谢谢
答案 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)
它:
最后一个为当前行生成“复制行”的函数是:
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] 范围内的日期数超过 可用的日期数,这些日期是重复。
您的受孕失败:例如 2019-09-28 的行(需要 30 行)。 在 [d-10:d-2] 范围内,应该取21个日期。
但是因为那里只有 9个日期,所以:
但是该范围仅包含 20 个日期,因此无法提取 21 从那里开始(无重复)。
结论:您的要求过高了。
再说一遍:
实际上可以从以下形式看出这一任务是不可能的 以下观察结果:
日期范围 [d-30:d-2] 包含 29 个日期。 因此,不要期望可以从该池中获取 30个不同的日期,而不管两个子范围之间的划分。