首页 > 解决方案 > AttributeError:“numpy.float64”对象没有属性“掩码”

问题描述

我正在尝试对齐抖动的图像,但我的代码不断给我以下错误:

AttributeError:“numpy.float64”对象没有属性“掩码”

这是代码:

import numpy as np
from astropy.io import fits
import glob
from astropy.stats import sigma_clip
from reproject.mosaicking import find_optimal_celestial_wcs
from reproject import reproject_interp

# In the line below, you may have called "mydata" something else in Assignment 1
calibrated_dir = '../mydata/M52_calibrated/'

# Use glob to create file list that includes images from *all* bands
filelist = glob.glob(calibrated_dir, '*.fit')

# Find the optimal shape of the canvas that will fit all the images, as well as the optimal wcs coordinates
wcs_out, shape_out = find_optimal_celestial_wcs(filelist,auto_rotate=True)
print('Dimensions of new canvas:',shape_out) # Should be bigger than the original 2048x2048 images we started with.

bands = ['PhotB','PhotV','PhotR']  # This is the list of the three filter names

for band in bands: # Loop through the three bands 
    # Get the list of all the files that were exposed in the current band
    filelist = glob.glob(calibrated_dir+'*'+band+'*')
    filelist = sorted(filelist)
    
    allexposures = [] # Declare an empty list.  Each item of the list will hold the data array of each file in filelist.
    airmass = [] # Declare an empty list.  Will hold the airmass of each file in filelist.
    texp = [] # Declare an empty list.  Will hold the exposure times.
    
    for f in filelist: 
        hdu = fits.open(f) #open the current file
        texp.append(hdu[0].header['EXPTIME']) # get the exposure time
        airmass.append(hdu[0].header['AIRMASS'])# get the air mass 

        # This line runs reproject_interp to map the pixels of the image to the pixels of the canvas we created above
        # new_image_data below has the same dimensions as the larger canvas.
        new_image_data = reproject_interp(f, wcs_out,shape_out=shape_out,return_footprint=False) 
        allexposures.append(new_image_data)

    # Turn the list of arrays into a 3D array
    allexposures = np.array(allexposures)

    # We have now aligned all the exposures onto the same pixels.  Combine them into a single image using sigma_clip and taking the mean.
    images_masked = sigma_clip(allexposures, sigma=3.0)  # Use sigma_clip to mask pixels more than 3 sigma from the mean of the exposures
    combined_image = np.ma.mean(images_masked)

    # np.ma.mean() sets pixels to 0 if there were no good pixels to take a mean.  The following lines set them to NaN instead.
    # NaN means "not a number" - easier to mask later on.
    mask = combined_image.mask
    combined_image = combined_image.data
    combined_image[mask] = np.nan

...

错误来自 line mask = images_combined.mask。我已经尝试过combined_image = np.ma.mean(images_masked.astype(float64))诸如此类的其他变体,但我无法摆脱错误。我是编码新手,这是一门课,所以请善待我真的不擅长这个。任何帮助是极大的赞赏。

标签: pythonlinuxnumpyastropy

解决方案


我没有使用astropy,但显然使用sigma_clip会产生一个屏蔽数组。为了显示

In [18]: arr = np.ma.masked_equal([[1,2,3],[2,2,1]],2)
In [19]: arr
Out[19]: 
masked_array(
  data=[[1, --, 3],
        [--, --, 1]],
  mask=[[False,  True, False],
        [ True,  True, False]],
  fill_value=2)

一个简单的平均值 - 在所有值上 - 产生一个数字:

In [20]: np.ma.mean(arr)
Out[20]: 1.6666666666666667

但是其中一个轴上的平均值会产生另一个屏蔽数组(在行或列中的所有元素也被屏蔽的情况下被屏蔽)。

In [21]: np.ma.mean(arr, axis=0)
Out[21]: 
masked_array(data=[1.0, --, 2.0],
             mask=[False,  True, False],
       fill_value=1e+20)
In [22]: np.ma.mean(arr, axis=1)
Out[22]: 
masked_array(data=[2.0, 1.0],
             mask=[False, False],
       fill_value=1e+20)

您尝试的替换工作:

In [36]: x=np.ma.mean(arr, axis=0)
In [37]: x
Out[37]: 
masked_array(data=[1.0, --, 2.0],
             mask=[False,  True, False],
       fill_value=1e+20)
In [38]: y = x.data
In [39]: y[x.mask] = np.nan
In [40]: y
Out[40]: array([ 1., nan,  2.])

一种更直接的方法:

In [47]: x=np.ma.mean(arr, axis=0)
In [48]: x.filled(np.nan)
Out[48]: array([ 1., nan,  2.])

推荐阅读