首页 > 解决方案 > 将蒙面 astropy Table 中的元素转换为 np.nan

问题描述

考虑读取包含一些无效条目的数据文件的简单过程。这是我的test.dat文件:

16        1035.22  1041.09    24.54     0.30     1.39     0.30     1.80     0.30     2.26     0.30     1.14     0.30     0.28     0.30   0.2884
127        824.57  1105.52    25.02     0.29     0.87     0.29     1.30     0.29     2.12     0.29     0.66     0.29     0.10     0.29   0.2986
182       1015.83   904.93    INDEF     0.28     1.80     0.28     1.64     0.28     2.38     0.28     1.04     0.28     0.06     0.28   0.3271
185       1019.15  1155.09    24.31     0.28     1.40     0.28     1.78     0.28     2.10     0.28     0.87     0.28     0.35     0.28   0.3290
192       1024.80  1045.57    24.27     0.27     1.24     0.27     2.01     0.27     2.40     0.27     0.90     0.27     0.09     0.27   0.3328
197       1035.99   876.04    24.10     0.27     1.23     0.27     1.52     0.27     2.59     0.27     0.45     0.27     0.25     0.27   0.3357
198       1110.80  1087.97    24.53     0.27     1.49     0.27     1.71     0.27     2.33     0.27     0.22     0.27     0.00     0.27   0.3362
1103      1168.39  1065.97    24.35     0.27     1.28     0.27     1.29     0.27     2.68     0.27     0.43     0.27     0.26     0.27   0.3388

这是读取它的代码,并将“坏”值 ( INDEF) 替换为浮点 ( 99.999)

import numpy as np
from astropy.io import ascii

data = ascii.read("test.dat", fill_values=[('INDEF', '0')])
data = data.filled(99.999)

这很好用,但是如果我尝试用 a 替换坏值np.nan(即,我使用 line data = data.filled(np.nan)),我会得到:

ValueError: cannot convert float NaN to integer

为什么会这样,我该如何解决?

标签: pythonastropy

解决方案


如前所述,问题是 numpyMaskedArray.filled()方法似乎在检查是否实际上有任何要填充的内容之前尝试将填充值转换为适当的类型。由于示例中的表有一int列,因此在 numpy 中失败(并且 astropy.Table 只是filled()在每一列上调用该方法)。

这应该有效:

In [44]: def fill_cols(tbl, fill=np.nan, kind='f'):
    ...:     """
    ...:     In-place fill of ``tbl`` columns which have dtype ``kind``
    ...:     with ``fill`` value.
    ...:     """
    ...:     for col in tbl.itercols():
    ...:         if col.dtype.kind == kind:
    ...:             col[...] = col.filled(fill)
    ...: 

In [45]: t = simple_table(masked=True)

In [46]: t
Out[46]: 
<Table masked=True length=3>
  a      b     c  
int64 float64 str1
----- ------- ----
   --     1.0    c
    2     2.0   --
    3      --    e

In [47]: fill_cols(t)

In [48]: t
Out[48]: 
<Table masked=True length=3>
  a      b     c  
int64 float64 str1
----- ------- ----
   --     1.0    c
    2     2.0   --
    3     nan    e

推荐阅读