others - python - 根据上1个的约束条件生成日期

我有一个dataframe df1,它的date_1列的值从01/09/2019到30/09/2019。

DF1


 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 16



我想使用带有约束的df1生成一个dataframe df2 :

date_2是根据df1中存在的计数特征生成的。

date_2 可以随机选择从范围(30 -date_1到date_1 -1 ),在例子,在 01/09/2019,从02/08/2019从30/08/2019,

预期输出:


 date_1 count date_2


 01/09/2019 5 02/08/2019


 01/09/2019 5 10/08/2019


 01/09/2019 5 12/08/2019


 01/09/2019 5 25/08/2019


 01/09/2019 5 28/08/2019


 02/09/2019 4 03/08/2019


 02/09/2019 4 10/08/2019


 02/09/2019 4 20/08/2019


 02/09/2019 4 25/08/2019



我能够使用以下函数生成date_2 :


def pick_random_delta_in_range(min_days=1, max_days=30):


 if min_days is None and max_days is None:


 return datetime.timedelta(days=1, minutes=0, seconds=0)


 if min_days is None:


 return max_days


 if max_days is None:


 return min_days


 days_to_be_added = random.randint(min_days, max_days)


 return datetime.timedelta(days=days_to_be_added, minutes=0, seconds=0)



def gen_date_by_delta(src_dates, date_format, delta_min, delta_max):


 gen_dates = []


 for dt in src_dates:


 src_date = datetime.datetime.strptime(dt, date_format)



 if src_date is None:


 gen_dates.append("")


 continue



 chosen_delta = pick_random_delta_in_range(min_days=delta_min, max_days=delta_max)



 result_date = (src_date + chosen_delta).strftime(date_format)


 gen_dates.append(result_date)



 return gen_dates



date_2 = gen_date_by_delta(src_dates=df1["date_1"], date_format=date_format, delta_min=1, delta_max=30)



我不想生成重复的条目。

我也无法理解如何根据计数复制数据框中的字段,并且相应地生成日期。

时间:

定义以下"replication"函数:


def repl(row):


 d1 = row.date_1


 cnt = row['count']


 dates = [ d1 - pd.Timedelta(n, 'D') for n in


 np.sort(np.random.choice(30, cnt, False))[::-1] ]


 return pd.DataFrame({'date_1': d1, 'count': cnt, 'date_2': dates})



然后应用它,连接结果并保存为DF2 :


DF2 = pd.concat(df.apply(repl, axis=1).tolist(), ignore_index=True)



如果要从范围中获取所有日期,请找到dates =...指令并将它更改为:


dates = pd.date_range('2019-08-01', '2019-09-30')



创建一个函数,该函数将数据框的一行作为参数,并从允许的日期中选择随机日期的数量,然后让它返回给定行数的数据框,你可以使用apply在每一行上使用此函数,然后你可以连接所有这些数据框。

若要不生成重复的'date_2'值,请使用 numpy random shuffle,它将随机改变数组中元素的顺序,你可以选择开头的n个元素。

这里我还使用Pandas date_range来生成日期范围,从这个范围中选取随机日期,这是一次(因为它们总是相同的,所以效率更高)完成的,然后在apply调用时将日期传递给makedate2函数。


def makedate2(row, dates):


 cnt = row['count']


 np.random.shuffle(dates) #randomly change the order of dates


 return pd.DataFrame({'date_1':row['date_1'],


 'count':cnt,


 'date_2':dates[:cnt]}


 )



alldates = pd.date_range(df['date_1'].min() - pd.Timedelta(30, unit='D'), df['date_1'].max() - pd.Timedelta(30, unit='D')).to_numpy()


res = df.apply(lambda x : makedate2(x, alldates), axis=1)


df2 = pd.concat(res.to_numpy()).reset_index(drop=True)



使用你提供的例子数据的可能的df2为:


 date_1 count date_2


0 2019-01-09 5 2019-09-26


1 2019-01-09 5 2019-09-11


2 2019-01-09 5 2019-05-18


3 2019-01-09 5 2019-10-15


4 2019-01-09 5 2019-06-06


.. ... ... ...


130 2019-09-14 16 2019-04-12


131 2019-09-14 16 2019-04-05


132 2019-09-14 16 2019-10-08


133 2019-09-14 16 2019-05-05


134 2019-09-14 16 2019-11-09



...