Generate random no of days based on random selection of columns

核能气质少年 提交于 2020-08-19 08:43:06

问题


I have a dataframe like as shown below. Thanks to SO community for helping with the below

df1 = pd.DataFrame({'person_id': [11,11, 12, 13, 14],
                        'date_birth': ['01/01/1961','12/30/1961', '05/29/1967', '01/01/1957', '7/27/1959']})
df1 = df1.melt('person_id', value_name='dates')
df1['dates'] = pd.to_datetime(df1['dates'])
df_ranges = df1.assign(until_prev_year_days=(df1['dates'].dt.dayofyear - 1),
     until_next_year_days=((df1['dates'] + pd.offsets.YearEnd(0)) - df1['dates']).dt.days)
f = {'until_prev_year_days': 'min', 'until_next_year_days': 'min'}

min_days = df_ranges.groupby('person_id',as_index=False).agg(f)
min_days.columns = ['person_id','min_days_to_prev_year','min_days_to_next_year']
df_offset = pd.merge(df_ranges[['person_id','dates']], min_days, on='person_id',how='inner')

What I would like to do is

a) create a new column called rand_number col based on rand value from min_days_to_prev_year or min_days_to_next_year cols

b) rand value for rand_number column is based on 2 conditions below

     a) rand_value from `min_days_to_prev_year` - `range is 0 to -N` (ex: 0 to -363 for person 11)
     b) rand_value from `min_days_to_next_year` - `range is 0 to +N` (ex: 0 to +1 for person 11)

It's possible that both columns have `0` as value, then we just take 0. 

c) would like to mention that the selection of column should be random (ex: some random subjects should have rand_value based on min_days_to_prev_year while others based on min_days_to_next_year)

I was trying something like below

df_offset['rand_number'] = np.random.randint(df_offset['min_days_to_prev_year'].astype(int),df_offset['min_days_to_next_year'].astype(int), df_offset.shape[0])

I expect my output to be like as shown below


回答1:


I would generate random on [0,1] and scale accordingly:

np.random.seed(10)
rand = np.random.random(len(df_offset))

df_offset['rand_number'] = (rand * (df_offset.min_days_to_next_year + df_offset.min_days_to_prev_year) 
                                 -  df_offset.min_days_to_prev_year
                           ).astype(int)

Output:

      person_id  dates                  min_days_to_prev_year    min_days_to_next_year    rand_number
--  -----------  -------------------  -----------------------  -----------------------  -------------
 0           11  1961-12-30 00:00:00                      363                        1            -82
 1           12  1967-05-29 00:00:00                      148                      216           -140
 2           13  1957-01-01 00:00:00                        0                      364            230
 3           14  1959-07-27 00:00:00                      207                      157             65



回答2:


You can try something like this:

>>> import random
>>> rand_numbers = pd.Series(random.randint(*sorted((0, -1*i if random.choice((0,1)) else j))) for i,j in zip(df_offset.min_days_to_prev_year, df_offset.min_days_to_next_year))
>>> df_offset['rand_numbers'] = rand_numbers
>>> df_offset
   person_id      dates  min_days_to_prev_year  min_days_to_next_year  rand_numbers
0         11 1961-12-30                    363                      1          -235
1         12 1967-05-29                    148                    216           168
2         13 1957-01-01                      0                    364             2
3         14 1959-07-27                    207                    157           132


来源:https://stackoverflow.com/questions/62535573/generate-random-no-of-days-based-on-random-selection-of-columns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!