科学的python数组语法

时间:2017-03-15 21:10:32

标签: python matlab computer-science montecarlo data-science

所以我在python中编写了这段代码。我不打算解释它,因为它是一个简单的语法修复,我似乎无法看到,因此解释它的用途是没用的。

我遇到的问题是,对于给定的d,例如15,我得到“cuentas”的值为“right”,“e”是正确的。

我想要做的是迭代一组d并获得每个cuentas的值,并且每个e以绘制d vs e。

我的问题是我似乎无法在python中创建矩阵。

在matlab中,我曾经写过两个不同的循环,比如theese:

for i=1:1:N
    for j=1:9

      a[i,j]= and so on

a [i,j]将是一个包含N行和9列的矩阵,我可以访问和操作。

在下面的代码中,我将故意将#comments放在我希望迭代距离的地方

import numpy as np
import matplotlib.pyplot as plt
N=100000
cos=np.zeros(N)
phi=np.zeros(N)
teta=np.zeros(N)
a=np.zeros(N)


xrn=np.zeros(N)
yrn=np.zeros(N)
zrn=np.zeros(N)

x=np.zeros(N)
y=np.zeros(N)
z=np.zeros(N)

lim1=14.7
lim2=3.35
lim3=-lim1
lim4=-lim2

#d=np.array([15,20,25,30,35,40,45,50,55])
d=15

    #for j in range(9):
for i in range(N):
    cos[i]=np.random.uniform(-1,1)
    teta[i]=np.random.uniform(-np.pi,np.pi)
    phi[i]=np.random.uniform(0,2*np.pi)

# a[i]=d[j]/cos[i]*np.cos(phi[i])
a[i]=d/cos[i]*np.cos(phi[i])


xrn[i]=np.random.uniform(-1,1)*lim1
yrn[i]=np.random.uniform(-1,1)*lim2

x[i]=a[i]*np.sin(teta[i])*np.cos(phi[i])+xrn[i]
y[i]=a[i]*np.sin(teta[i])*np.sin(phi[i])+yrn[i]

#cuentas[j]=0
cuentas=0

#for j in range(9):
for i in range(N):
    if a[i]>0 and x[i] < lim1 and x[i]>lim3 and y[i] < lim2 and y[i]>lim4:
        cuentas=cuentas+1
#e[j]=cuenta[j]/N
e=cuentas/N

非常感谢那些阅读的人!

3 个答案:

答案 0 :(得分:1)

您可以使用numpy以下列方式在python中创建矩阵:

n=5
k=4
a=np.zeros([n,k])
for i in range(n):
    for j in range(k):
        a[i,j]=i+j
print(a)

结果是

[[ 0.  1.  2.  3.]
 [ 1.  2.  3.  4.]
 [ 2.  3.  4.  5.]
 [ 3.  4.  5.  6.]
 [ 4.  5.  6.  7.]]

答案 1 :(得分:1)

简短版本:

这与Python中的MATLAB代码完全等效

a = np.zeros([N, 9])
for i in range(N):
    for j in range(9):
        a[i,j]= and so on

唯一的主要区别是你需要预先定义数组,如果你希望你的代码具有合理的性能,那么你在MATLAB中也应该这样做。

但是,如果您事先不知道大小,可以在Python中使用列表,然后在最后转换为numpy数组。这将比大型数组的MATLAB示例快得多,因为列表和矩阵/数组的处理方式如下:

a = []
for i in range(N):
    a.append([])
    for j in range(9):
        a[-1].append( and so on
a = np.array(a)

[-1]表示(“{1}}的最后一个元素”,a表示列表末尾括号内的内容。append表示“将a[-1].append(foo)放在foo的最后一个元素中。

长版:

您的MATLAB代码将以大致相同的方式在Python中运行,但您需要考虑一些值得注意的差异。

首先,分配给大于现有数组/矩阵的索引在MATLAB中工作但不在numpy中。因此,如果你有一个大小a数组/矩阵,在MATLAB中你可以分配给元素[5, 5],但你不能在numpy。这意味着在MATLAB中你可以从一个空数组开始,而在numpy中你必须事先设置数组大小。请注意,MATLAB矩阵实际上无法调整大小,实际上每次通过循环时都会生成一个新矩阵并将所有数据复制到它。这非常慢,这就是MATLAB警告您预先分配数组的原因。 Numpy只是不假装能够调整数组大小,所以你需要更明确地做复制,预分配或使用列表(可以调整大小)。

其次,类似地,MATLAB不需要在使用之前定义矩阵,而numpy则需要。这是因为传统上MATLAB有三种数据结构(矩阵,单元数组和结构),每种数据结构都有自己的索引样式。因此,MATLAB可以根据索引的方式确定要创建的数据结构类型。 Python只有一种索引样式,所以它不能做出这种猜测。

第三,在MATLAB中使用单个数组大小与一些(但不是全部)函数创建一个2D方形矩阵,每个维度都是该大小,而在numpy中它创建一个1D数组。我不确定你的代码是否是你期望的。坦率地说,我不知道为什么MATLAB会这样工作。

第四,numpy数组可以有任意数量的维度,0(标量),1(向量),2,3,4等。另一方面,MATLAB矩阵必须至少有两个维度。这可能会导致一些意想不到的差异,例如转换为numpy向量无效。

至于你的Python代码,如果没有你说出了什么问题,我无法告诉你如何修复它。但希望我已经给你足够的信息来自己做。

答案 2 :(得分:0)

所以我已经采纳了你的答案并且它有效!

如果有人想知道它是蒙特卡罗模拟有多少粒子将通过两个矩形探测器。当我从探测器1抛出粒子时,它们通过它是微不足道的,我计算通过探测器2的数字。

更正的代码是

N=100000
"La dirección viene dada por v=[rsin(teta)*cos(phi),rsin(teta)sin(phi),rcos(teta)]"
"Los vectores que vamos a usar debemos inicializarlos como un vector de ceros"
cos=np.zeros([10,N])
phi=np.zeros([10,N])
teta=np.zeros([10,N])
a=np.zeros([10,N])

xrn=np.zeros(N)
yrn=np.zeros(N)
zrn=np.zeros(N)

x=np.zeros([10,N])
y=np.zeros([10,N])
z=np.zeros([10,N])

lim1=14.7
lim2=3.35
lim3=-lim1
lim4=-lim2
"d son las disversas distancias a las que colocamos la fuente con respecto al detector"

d=np.array([0.00001,15,20,25,30,35,40,45,50,55])

"e es la eficiencia geométrica simulada"
e=np.zeros(10)

"Debemos definir el coseno como números aleatorios en vez de el ángulo teta, debido a que queremos"
"que se distribuyan uniformemente por toda la esfera"
for j in range(10):
    for i in range(N):
        cos[j,i]=np.random.uniform(0,1)

        phi[j,i]=np.random.uniform(0,2*np.pi)

        a[j,i]=d[j]/cos[j,i]

        xrn[i]=np.random.uniform(-1,1)*lim1
        yrn[i]=np.random.uniform(-1,1)*lim2

        x[j,i]=a[j,i]*np.sin(math.acos(cos[j,i]))*np.cos(phi[j,i])+xrn[i]
        y[j,i]=a[j,i]*np.sin(math.acos(cos[j,i]))*np.sin(phi[j,i])+yrn[i]


cuentas=np.zeros(10)
for j in range(10):
    for i in range(N):
        if a[j,i]>0 and x[j,i] < lim1 and x[j,i]>lim3 and y[j,i] < lim2 and y[j,i]>lim4:
            cuentas[j]=cuentas[j]+1

    e[j]=cuentas[j]/N

感谢所有人!