Python 创建随机值并将其传递给具有硬边界的数据帧

Python 创建随机值并将其传递给具有硬边界的数据帧,python,python-3.x,pandas,numpy,Python,Python 3.x,Pandas,Numpy,我正在尝试使用随机值模拟熊猫数据帧,并结合硬上限/下限值。我使用的是np.random.normal,因为原始数据是相当正态分布的 我用来创建数据帧的代码是: df=pd.DataFrame({ “温度”:np.随机正常(6.809892,2.975827,93), “太阳”:np.随机.正常(1.615054,2.053996,93), “相对嗡嗡声”:np.随机.正常(87.153118,5.529958,93) }) 在上面的例子中,我希望这三个值都有一个硬的上下限。例如,Rel。哼无法

我正在尝试使用随机值模拟熊猫数据帧,并结合硬上限/下限值。我使用的是np.random.normal,因为原始数据是相当正态分布的

我用来创建数据帧的代码是:

df=pd.DataFrame({
“温度”:np.随机正常(6.809892,2.975827,93),
“太阳”:np.随机.正常(1.615054,2.053996,93),
“相对嗡嗡声”:np.随机.正常(87.153118,5.529958,93)
})
在上面的例子中,我希望这三个值都有一个硬的上下限。例如,Rel。哼无法低于0或高于100。编辑:所有三个值的上限或下限都不相同。温度可以变为负值,而太阳的边界为0和24)

如何在创建相对正态分布的同时强制这些值,并同时将它们传递给数据帧?

尝试使用函数绑定这些值,例如:

>>> df[df['Rel Hum']>100].head()
        Temp       Sun     Rel Hum
32  4.734005  4.102939  100.064077
Name: Rel Hum, Length: 93, dtype: float64
>>> df[df['Rel Hum']>100].head()
        Temp       Sun     Rel Hum
32  4.734005  4.102939  100.064077
>>> df['Rel Hum'].clip(0, 100, inplace=True) # assigns values outside boundary to 0 and 100 
>>> df.head()
       Temp       Sun    Rel Hum
0  9.714943  6.255931  93.105135
1  0.551001  3.063972  85.923184
2  7.780588  3.580514  79.124139
3  3.766066  3.684801  84.543149
4  8.541507 -3.066196  83.598925
>>> df[df['Rel Hum']>100].head()
Empty DataFrame
Columns: [Temp, Sun, Rel Hum]
Index: []

只需做一个
剪辑

df = pd.DataFrame({
    "Temp": np.random.normal(6.809892, 2.975827,93),
    "Sun": np.random.normal(1.615054,2.053996,93),
    "Rel Hum": np.random.normal(87.153118,5.529958,93)
}).clip(0,100)
并绘制:

df.plot.density(subplots=True);
给出:


您可以
剪裁
,但这样会在边缘留下尖刺:

import pandas as pd
import numpy as np

N = 10**5
df = pd.DataFrame({"Rel Hum": np.random.normal(87.153118,5.529958, N)})

df['Rel Hum'].clip(lower=0, upper=100).plot(kind='hist', bins=np.arange(60,101,1))


如果您希望避免该尖峰重新绘制边界外点,直到所有内容都在边界内:

while not df['Rel Hum'].between(0, 100).all():
    m = ~df['Rel Hum'].between(0, 100)
    df.loc[m, 'Rel Hum'] = np.random.normal(87.153118, 5.529958, m.sum())

df['Rel Hum'].plot(kind='hist', bins=np.arange(60,101,1))

编辑:请注意,对于给定参数,此样本来自截断的正态分布,很可能不是真正的正态分布,抱歉造成混淆

使用scipy定义为:

此分布的标准形式是截断为[a,b]范围的标准正态分布


感谢您的更正

你可以在生成数字后重新绘制,但是在边缘会有微小的尖峰。你可以剪裁端点,或者从该分布重新绘制,直到在边界内得到一个点。无论哪种方式,它都不会是真正正常的。然后我如何将这些值传递到pandas数据帧中?@clauria
pd.dataframe({'Col1':samples})
@ALollz是的,它看起来不“正常”,但它确实从截断的正常中采样;实际上,我不确定OP的意思是什么,好像他们想从截断的法线采样或从法线剪切。这两种情况最终都不会正常,这在很大程度上取决于参数,但我同意我的答案可能会令人困惑。@NaturalFrequency:谢谢。这起作用了perfectly@Clauric,请注意编辑和您的样本不是正态分布的事实,如果这是您要做的,那么剪辑更好。
from scipy.stats import truncnorm
low_bound = 0
upper_bound = 100
mean = 8
std = 2
a, b = (low_bound - mean) / std, (upper_bound - mean) / std
n_samples = 1000

samples = truncnorm.rvs(a = a, b = b,
                        loc = mean, scale = std,
                        size = n_samples)