缩短Python程序

时间:2014-02-19 13:27:38

标签: python

我有22个具有相同字段/列名称的FITS文件。我使用pyfits加载它们,例如:

hdulist1 = pyfits.open('/home/ssridhar/mock_test_files/Roncarelli_test/roncarelli_dist_halo1.fits')
hdulist2 = pyfits.open('/home/ssridhar/mock_test_files/Roncarelli_test/roncarelli_dist_halo2.fits')

然后我同样加载22个文件的表数据

tbdata1 = hdulist1[1].data
tbdata2 = hdulist2[1].data

由于我说的所有字段名称都相同

fields = ['ra','dec','zcosmo','r200','m200','is_central','r']

并将变量从1到22(var1,var2等)分配给字段,如:

var1 = dict((f, tbdata1.field(f)) for f in fields)
var2 = dict((f, tbdata2.field(f)) for f in fields)

现在我使用np.histogram同样找到22个文件的一些值:

N_1, r_hist_1 = np.histogram(var1['r'], bins=20, range=None, normed=False, weights=None)
N_2, r_hist_2 = np.histogram(var2['r'], bins=20, range=None, normed=False, weights=None)

现在我发现使用公式变量的值我同样为不同的文件命名sigma_num_1,sigma_num_2:

dist_1 = r_hist_1[1]
area_1 = [math.pi*(R**2-r**2) for R, r in zip(dist_1[1:], dist_1)]
sigma_num_1 = N_1/area_1

代码工作正常,并为我提供了sigma_num_1,sigma_num_2等的结果。

我不想为22个文件中的每个文件写上面的三行来查找sigma_num_3到sigma_num_22。 有没有办法做到这一点。找到sigma的所有22个值后,我需要找到所有这22个值的平均值。

5 个答案:

答案 0 :(得分:2)

您无需为每个值指定变量名称。您可以使用data structure存储所有值,同时为您提供引用每个值的便捷方式。诀窍是抽象在同一类变量的不同出现之间发生变化的部分,例如hdulist1hdulist2之间的差异。

例如,您可以通过将hdulist放入列表并使用open字符串方法形成每个format语句来创建hdulists = [] for n in range(1, 23): # range is exclusive so you get 1-22 hdulists.append( pyfits.open( ('/home/ssridhar/mock_test_files/Roncarelli_test' '/roncarelli_dist_halo{0}.fits').format(n) ) )

hdulists = [pyfits.open(
                ('/home/ssridhar/mock_test_files/Roncarelli_test'
                '/roncarelli_dist_halo{0}.fits').format(n)
            ) for n in range(1, 23)]

这也可以在列表理解中完成:

hdulist1

现在,您唯一需要记住的是python列表从索引0开始,因此您将hdulists[0]引用为.fits,依此类推。

但是你可以变得更聪明,并在一个函数内一次完成所有这些步骤,这将返回你想要的结果。然后为每个def sigma_num(n): fields = ['ra','dec','zcosmo','r200','m200','is_central','r'] hdulist = pyfits.open( ('/home/ssridhar/mock_test_files/Roncarelli_test' '/roncarelli_dist_halo{0}.fits').format(n) ) var = dict((f, hdulist[1].data.field(f)) for f in fields) N, r_hist = np.histogram(var['r'], bins=20, range=None, normed=False, weights=None) area = [math.pi*(R**2-r**2) for R, r in zip(r_hist[1:], r_hist)] return N/area 文件运行该功能。

sigma_num(3)

现在,您只需致电sigma_num(22)sigma_num_3即可获得您曾经称呼sigma_num_22sigma_nums = [] for n in range(1, 23): sigma_nums.append(sigma_num(n)) avg_sigma_num = sum(sigma_nums)/len(sigma_nums) 的内容。

要查找平均值,您可以使用我之前设定的技术来迭代范围:

sum

lentbdatabuiltin functions。您还可以将上述内容抽象为列表推导,甚至是更好的函数。

修改:由于您要求单独提供sigma_num,请将该部分功能分成帮助功能。 def tbdata(n): """ helper function """ hdulist = pyfits.open( ('/home/ssridhar/mock_test_files/Roncarelli_test' '/roncarelli_dist_halo{0}.fits').format(n) ) return hdulist[1].data def sigma_num(n): fields = ['ra','dec','zcosmo','r200','m200','is_central','r'] tbdata = tbdata(n) var = dict((f, tbdata.field(f)) for f in fields) N, r_hist = np.histogram(var['r'], bins=20, range=None, normed=False, weights=None) area = [math.pi*(R**2-r**2) for R, r in zip(r_hist[1:], r_hist)] return N/area 可以调用辅助函数:

{{1}}

答案 1 :(得分:1)

使用列表和循环。

hdulist = []
fits_path= '/home/ssridhar/mock_test_files/Roncarelli_test/roncarelli_dist_halo%i.fits'
for number in range(1,23):
    hdulist.append(pyfits.open(fits_path % number)
tbdata = [hdu[1].data for hdu in hdulist]

等...

答案 2 :(得分:1)

基本上,您要为每个文件计算“sigma”。因此,您可以创建一个将文件作为参数的函数,并返回'sigma'。

您可以将所有文件存储在列表中,并在循环列表时调用此函数。您可以将'sigmas'存储在另一个列表中。类似的东西:

>>> def sigma(file):
...     pass
... 
>>> files = ["a", "b"]
>>> sigmas = []
>>> for f in files:
...     sigmas.append(sigma(f)
... 
>>> sigmas
[None, None]

答案 3 :(得分:1)

首先,创建一个处理单个文件并计算其sigma的函数

def find_sigma(n):
    fields = ['ra','dec','zcosmo','r200','m200','is_central','r']
    hdulist = pyfits.open('/home/ssridhar/mock_test_files/Roncarelli_test/roncarelli_dist_halo%d.fits' % n)
    tbdata = hdulist[1].data
    var = dict((f, tbdata.field(f)) for f in fields)
    N, r_hist = np.histogram(var['r'], bins=20, range=None, normed=False, weights=None)
    dist = r_hist[1]
    area = [math.pi*(R**2-r**2) for R, r in zip(dist[1:], dist)]
    sigma_num = N/area

    return sigma_num

然后只需使用list comprehension查找平均值:

average_sigma = sum([find_sigma(i) for i in range(1, 23)]) / 23.0

答案 4 :(得分:0)

使用嵌套字典,为其分配22个密钥,并将每个数据点存储为主字典中的子字典。

e.g。

main_data = {}
for i in range(0,22):
  main_data['hdulist_{0}'.format(i)] = pyfits.open('/home/ssridhar/mock_test_files/Roncarelli_test/roncarelli_dist_halo{0}.fits'.format(i))