是否可以在没有for循环的情况下对存储在字典中的数组的值求和?

时间:2016-02-15 02:31:24

标签: python arrays dictionary

所以我觉得我可能已将自己编入角落 - 但我在这里。

我已经创建了一个数组字典(特别是ascii Columns),因为我需要创建五个数组,在一个具有五个不同参数的数组上执行相同的计算(计算包括乘以数组和五个任意常数之一)。

我现在想要创建一个数组,其中每个元素对应于来自所有五个数组的等效元素的总和。我宁愿不使用我已创建的丑陋循环(也很难检查我是否能通过循环获得正确答案)。

这是一个经过修改的测试代码段!

import numpy as np
from astropy.table import Column
from pylab import *

# The five paramaters for the Columns 
n1 = [14.18,19.09,33.01,59.73,107.19,172.72] #uJy/beam
n2 = [14.99,19.04,32.90,59.99,106.61,184.06] #uJy/beam
n1 = np.array([x*1e-32 for x in n1]) #W/Hz
n2 = np.array([x*1e-32 for x in n2]) #W/Hz


# an example of the arrays being mathed upon
luminosity=np.array([2.393e+24,1.685e+24,2.264e+23,5.466e+22,3.857e+23,4.721e+23,1.818e+23,3.237e+23])
redshift = np.array([1.58,1.825,0.624,0.369,1.247,0.906,0.422,0.66])

field = np.array([True,True,False,True,False,True,False,False])

DMs = {}
for i in range(len(n1)):
    DMs['C{0}'.format(i)]=0

for SC,SE,level in zip(n1,n2,DMs):
    DMmax = Column([1 for x in redshift], name='DMmax')
    DMmax[field]=(((1+redshift[field])**(-0.25))*(luminosity[field]/(4*pi*5*SE))**0.5)*3.24078e-23
    DMmax[~field]=(((1+redshift[~field])**(-0.25))*(luminosity[~field]/(4*pi*5*SC))**0.5)*3.24078e-23
    DMs[level] = DMmax

全部谢谢!

3 个答案:

答案 0 :(得分:2)

Numpy就是为此而建的! (假设所有阵列的形状相同)

只需添加它们,numpy将通过数组以元素方式移动。这也比在Python层中使用for循环快几个数量级。

示例:

>>> n1 = np.array([1,2,3])
>>> n2 = np.array([1,2,3])
>>> total = n1 + n2
>>> total
array([2,4,6])
>>> mask = np.array([True, False, True])
>>> n1[mask] ** n2[mask]
array([ 1, 27])

修改其他输入

你可能会做这样的事情:

SE_array = (((1+redshift[field]) ** (-0.25)) * (luminosity[field]/(4*pi*5*n1[field])) ** 0.5) * 3.24078e-23
SC_array = (((1+redshift[field]) ** (-0.25)) * (luminosity[field]/(4*pi*5*n2[field])) ** 0.5) * 3.24078e-23

并通过堆叠新数组来建立关联:

DM = np.dstack((SE_array, SC_array))
reshaper = DM.shape[1:]    # take from shape (1, 6, 2) to (6,2), where 6 is the length of the arrays
DM = DM.reshape(reshaper)

这将为您提供像:

这样的二维数组
array([[SE_1, SC_1],
       [SE_2, SC_2]])

希望这是有帮助的

答案 1 :(得分:1)

如果你不能只是添加numpy数组,你可以将复合数组的创建提取到函数中。

def get_element(i):
    global n1, n2, luminosity, redshift, field

    return n1[i] + n2[i] + luminosity[i] + redshift[i] + field[i]

L = len(n1)
composite = [get_element(i) for i in range(L)]

答案 2 :(得分:0)

答案是盯着我,但感谢@willnx,@ cricket_007和@ andrew-lavq。您的建议让我意识到解决方案的简单性。

  

只需添加它们,numpy将通过数组以元素方式移动。 - willnx

     

您需要一个循环来汇总集合的所有值 - cricket_007

所以它真的像

一样简单

sum(x for x in DMs.values())

我不确定这是否是最快的解决方案,但我认为这是最简单的解决方案。