Python 生成大型模拟并将同一阵列多次插入不同位置的另一阵列
我正在为油井进行蒙特卡罗模拟。最终目标是使所有油井具有平滑的概率生产曲线。我已经尽我所能优化了,但是当我使用我的完整数据集和我想要的模拟数量时,我列出的3条apply语句中的每一条都花费了很多时间。(小时)我包含的代码有10次迭代。如果你把它提高到10000,这是目标,它真的开始拖 我已经生成了一个熊猫,它拥有我想要建模的所有未来油井,并且有可能选择下一个要钻探的油井 然后我创建了一个panda,在这里我将所有的东西都分为我想要用来计算模型选择井的顺序的类别。所以我的“计时”熊猫包含了我的分类,以及这些分类中的每一个油井指数的数组,以及油井概率的数组 这一切都在几秒钟内完成。下一部分工作正常,但速度非常慢 接下来,我使用一个带有百分比的numpy生成器选项来随机生成用于I模拟的井的顺序。正如其他帖子所指出的,@njit不适用于概率数组。结果是,阵列的1维是每个类别选择井的顺序,另一维是每个模拟。大约有150个类别,每个类别中有10000口井。我希望运行10000次模拟Python 生成大型模拟并将同一阵列多次插入不同位置的另一阵列,python,arrays,pandas,numpy,numba,Python,Arrays,Pandas,Numpy,Numba,我正在为油井进行蒙特卡罗模拟。最终目标是使所有油井具有平滑的概率生产曲线。我已经尽我所能优化了,但是当我使用我的完整数据集和我想要的模拟数量时,我列出的3条apply语句中的每一条都花费了很多时间。(小时)我包含的代码有10次迭代。如果你把它提高到10000,这是目标,它真的开始拖 我已经生成了一个熊猫,它拥有我想要建模的所有未来油井,并且有可能选择下一个要钻探的油井 然后我创建了一个panda,在这里我将所有的东西都分为我想要用来计算模型选择井的顺序的类别。所以我的“计时”熊猫包含了我的分类,
- a是可以选择的油井索引数组
- size是该数组的长度
- per是每口井被选中的概率
- 顺序是每个模拟钻井顺序的数组
- 指数是那口井的指数
- 订单是每口井钻井的时间(以月为单位)
- 曲线是作为列表传递的生产曲线
- m是所有模拟中钻井月份的最高值
干杯。这显然是一个经过充分研究的问题,但它不是最小的或可复制的。如果我是你,我会分析代码,找到瓶颈并提出相关问题,包括一些其他人可以使用的虚假数据。从更实际的角度来看,
np。选择
可能很慢,无需更换。请参阅,了解一种可能的解决方法。最后一件事-将numba装饰器应用于诸如TimingGenerator或OrderGenerator之类的高级函数可能会增加很少的速度,甚至会使程序变慢。Numba无法神奇地重写numpy代码以提高效率。你可以在有或没有装饰器的情况下测试每一个函数,看看什么最有效。谢谢@hilberts\u。我使用了jit,你在其中两个函数上都是正确的,速度稍微慢了一点。不过,我可以申请njit的速度要快得多。我为随机选择更新了np.generator,它确实将10000次模拟的速度从9分钟提高到了8分钟。我还试图得到一套工作的代码。不确定它是否符合您的标准。干杯
import numpy as np
from numba import njit
import datetime
import math
def TimingGenerator(a, size, p):
i = 10
g = np.random.Generator(np.random.PCG64())
order = np.concatenate([g.choice(a=a, size=size, replace=False, p=p) for z in range(i)]).reshape(i, size)
return order
@njit
def OrderGenerator(order, index):
result = np.where(order == index)[1]
return result
def CurveAverager(order, curve, m):
matrix = np.array([[0] * math.ceil(i) + curve + [0] * int((m - math.ceil(i))) for i in order])
result = np.mean(matrix, axis=0)
return result
begin_time = datetime.datetime.now()
size = 8000
g = np.random.Generator(np.random.PCG64())
a = g.choice(20_000, size=size, replace=False)
p = np.random.randint(1,100, size=size)
p = p/np.sum(p)
for i in range(150):
q = TimingGenerator(a,size,p)
print(datetime.datetime.now() - begin_time)
index = np.amin(q)
for i in range(100000):
order = OrderGenerator(q, index)
print(datetime.datetime.now() - begin_time)
order = order / 15
curve = list(range(600, 0, -1))
for i in range(20000):
avgcurve = CurveAverager(order, curve, size)
print(datetime.datetime.now() - begin_time)