在熊猫中产生一个平均数为20的2-40之间的随机数,作为熊猫的一列。

问题描述 投票:1回答:1

我有一个数据框架,如下图所示

session      slot_num     appt_time
s1           1            2020-01-06 09:00:00
s1           2            2020-01-06 09:20:00
s1           3            2020-01-06 09:40:00
s1           3            2020-01-06 09:40:00
s1           4            2020-01-06 10:00:00
s1           4            2020-01-06 10:00:00
s2           1            2020-01-06 08:20:00
s2           2            2020-01-06 08:40:00
s2           2            2020-01-06 08:40:00
s2           3            2020-01-06 09:00:00
s2           4            2020-01-06 09:20:00
s2           5            2020-01-06 09:40:00
s2           5            2020-01-06 09:40:00
s2           6            2020-01-06 10:00:00
s3           1            2020-01-09 13:00:00
s3           1            2020-01-09 13:00:00
s3           2            2020-01-09 13:20:00
s3           3            2020-01-09 13:40:00

在上面我想添加一个叫做service_time的列。

service_time应该包含2到40之间的任何随机数字,每个会话的平均数为20。

我希望随机数遵循随机正态分布,平均数为20,标准差为10,最小为2,最大为40。

预期产出。

session      slot_num     appt_time               service_time
s1           1            2020-01-06 09:00:00     30
s1           2            2020-01-06 09:20:00     10
s1           3            2020-01-06 09:40:00     15
s1           3            2020-01-06 09:40:00     35
s1           4            2020-01-06 10:00:00     20
s1           4            2020-01-06 10:00:00     10
s2           1            2020-01-06 08:20:00     15
s2           2            2020-01-06 08:40:00     20
s2           2            2020-01-06 08:40:00     25
s2           3            2020-01-06 09:00:00     30
s2           4            2020-01-06 09:20:00     20
s2           5            2020-01-06 09:40:00     8
s2           5            2020-01-06 09:40:00     40
s2           6            2020-01-06 10:00:00     2
s3           1            2020-01-09 13:00:00     4
s3           1            2020-01-09 13:00:00     32
s3           2            2020-01-09 13:20:00     26
s3           3            2020-01-09 13:40:00     18

注:请注意,这是一个遵循上述最小、最大和平均标准的随机组合。

pandas numpy random pandas-groupby
1个回答
1
投票

用cutom函数的一种可能的解决方案。

#https://stackoverflow.com/a/39435600/2901002
def gen_avg(n, expected_avg=20, a=2, b=40):
    while True:
        l = np.random.randint(a, b, size=n)
        avg = np.mean(l)

        if avg == expected_avg:
            return l

df['service_time'] = df.groupby('session')['session'].transform(lambda x: gen_avg(len(x)))
print (df)
   session  slot_num            appt_time  service_time
0       s1         1  2020-01-06 09:00:00            31
1       s1         2  2020-01-06 09:20:00             9
2       s1         3  2020-01-06 09:40:00            23
3       s1         3  2020-01-06 09:40:00            37
4       s1         4  2020-01-06 10:00:00             6
5       s1         4  2020-01-06 10:00:00            14
6       s2         1  2020-01-06 08:20:00            33
7       s2         2  2020-01-06 08:40:00            29
8       s2         2  2020-01-06 08:40:00            18
9       s2         3  2020-01-06 09:00:00            32
10      s2         4  2020-01-06 09:20:00             9
11      s2         5  2020-01-06 09:40:00            26
12      s2         5  2020-01-06 09:40:00            10
13      s2         6  2020-01-06 10:00:00             3
14      s3         1  2020-01-09 13:00:00            19
15      s3         1  2020-01-09 13:00:00            22
16      s3         2  2020-01-09 13:20:00             5
17      s3         3  2020-01-09 13:40:00            34

1
投票

这是一个利用NumPy新的生成器基础设施的解决方案. 请看 文件 来讨论这个和旧的RandomState基础架构之间的差异。

import numpy as np
from numpy.random import default_rng

# assuming df is the name of your dataframe
n = len(df)

# set up random number generator
rng = default_rng()

# sample more than enough values
vals = rng.normal(loc=20., scale=10., size=2*n)

# filter values according to cut-off conditions
vals = vals[2 <= vals]
vals = vals[vals <= 40]

# add n random values to dataframe
df['service_time'] = vals[:n]

1
投票

正态分布有一个无边界的范围,所以如果你的边界在2和40之间,那么这个分布就不是正态分布。 一个有边界的替代方案,并避免了接受拒绝方案,是使用 三角分布 (详见维基百科). 由于三角形分布的平均数是 (left + mode + right) / 3,与 left = 2right = 40 你会设置 mode = 18 以获得理想的平均值20。

© www.soinside.com 2019 - 2024. All rights reserved.