使用组合或另一种技巧迭代遍历3种不同的数组?

2024-09-28 01:28:32 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑我的代码

a,b,c = np.loadtxt ('test.dat', dtype='double', unpack=True)

a、b和c是相同的数组长度。你知道吗

for i in range(len(a)):

   q[i] = 3*10**5*c[i]/100
   x[i] = q[i]*math.sin(a)*math.cos(b)
   y[i] = q[i]*math.sin(a)*math.sin(b)
   z[i] = q[i]*math.cos(a)
我试图找出X、Y、Z 2点之间的差值的所有组合来迭代这个方程(席XJ)+(Y-YJ)+(Zi-ZJ)=R

我用这个密码

for combinations in it.combinations(x,2):
   xdist =  (combinations[0] - combinations[1])
for combinations in it.combinations(y,2):
   ydist =  (combinations[0] - combinations[1])
for combinations in it.combinations(z,2):
   zdist =  (combinations[0] - combinations[1])

r = (xdist + ydist +zdist) 

对于我拥有的一个大文件来说,python需要很长时间,我想知道是否有一种更快的方法来获取r的数组,最好是使用嵌套循环?你知道吗

例如

if i in range(?):
     if j in range(?):

Tags: 代码inforifnprangeitmath
3条回答

嗯,你的计算很复杂。此外,如果要将所有r值存储在一个列表中,则需要大量内存。通常,您不需要一个列表,一个生成器可能就足够处理这些值了。你知道吗

考虑以下代码:

def calculate(x, y, z):
    for xi, xj in combinations(x, 2):
        for yi, yj in combinations(y, 2):
            for zi, zj in combinations(z, 2):
                yield (xi - xj) + (yi - yj) + (zi - zj)

它返回一个生成器,每次调用生成器的next()方法时只计算一个值。你知道吗

gen = calculate(xrange(10), xrange(10, 20), xrange(20, 30))
gen.next() # returns -3
gen.next() # returns -4 and so on

既然您显然在使用numpy,那么让我们实际使用numpy;它会更快。如果在使用numpy时完全避免python循环,而是使用它的矢量化数组操作,那么它几乎总是更快,而且通常更容易阅读。你知道吗

a, b, c = np.loadtxt('test.dat', dtype='double', unpack=True)

q = 3e5 * c / 100  # why not just 3e3 * c?
x = q * np.sin(a) * np.cos(b)
y = q * np.sin(a) * np.sin(b)
z = q * np.cos(a)

现在,后面的示例代码并没有完成您可能希望它做的事情—注意您每次都是如何说xdist = ...?您正在覆盖该变量,而没有对其执行任何操作。我假设你想要每对点之间的平方欧几里德距离,使矩阵dists,其中dists[i, j]等于第i点和第j点之间的距离。你知道吗

简单的方法是,如果您有可用的scipy:

# stack the points into a num_pts x 3 matrix
pts = np.hstack([thing.reshape((-1, 1)) for thing in (x, y, z)])

# get squared euclidean distances in a matrix
dists = scipy.spatial.squareform(scipy.spatial.pdist(pts, 'sqeuclidean'))

如果你的列表很大,不使用squareform会更节省内存,但是它是一种压缩格式,要找到特定的距离对有点困难。你知道吗

稍微难一点,如果你不能/不想使用scipy:

pts = np.hstack([thing.reshape((-1, 1)) for thing in (x, y, z)])
sqnorms = np.sum(pts ** 2, axis=1)
dists = sqnorms.reshape((-1, 1)) - 2 * np.dot(pts, pts.T) + sqnorms

它基本上实现了公式(a-b)^2=a^2-2ab+b^2,但都是向量。你知道吗

很抱歉没有发布完整的解决方案,但是您应该避免嵌套对range()的调用,因为每次调用range()时,它都会创建一个新的元组。最好调用range()一次并存储结果,或者使用循环计数器。你知道吗

例如,而不是:

max = 50

for number in range (0, 50):

    doSomething(number)

…你会做:

max = 50
current = 0

while current < max:

    doSomething(number)
    current += 1

相关问题 更多 >

    热门问题