numpy genfromtxt 未应用 missing_values

numpy genfromtxt not applying missing_values

我目前正在努力解决一个非常简单的问题,但似乎无法解决。您可以使用以下文件和代码重现该问题:

test.csv

2020081217,28.6
2020081218,24.7
2020081219,-999.0
2020081220,-999.0
2020081221,-999.0

代码

data = np.genfromtxt("C:/Users/col/Downloads/test.csv", delimiter=',', missing_values=["-999", "-999.0", -999, -999.0])
print(data)

输出

[[ 2.02008122e+09  2.86000000e+01]
 [ 2.02008122e+09  2.47000000e+01]
 [ 2.02008122e+09 -9.99000000e+02]
 [ 2.02008122e+09 -9.99000000e+02]
 [ 2.02008122e+09 -9.99000000e+02]]

为什么 none 的 missing_values 版本会捕获文件中的 -999 并将其替换为 NaN 或类似的东西?我觉得这应该很简单(并且可能已经在本网站的某处回答过),但我无法弄清楚...感谢您的帮助。

您需要添加usemask=True

data = np.genfromtxt("test.csv", delimiter=',', usemask=True, missing_values=-999.0)

用 NAN 填充。

data = data.filled(np.nan)

检查 NAN。

np.isnan(data)

输出。

array([[False, False],
   [False, False],
   [False,  True],
   [False,  True],
   [False,  True]])

缺失值有两种类型。一种是值仅由分隔符表示的地方。默认填充为nan,但我们可以定义一个单独的填充:

In [93]: txt1="""2020081217,28.6
    ...: 2020081218,24.7
    ...: 2020081219,
    ...: 2020081220,
    ...: 2020081221,"""
In [94]: np.genfromtxt(txt1.splitlines(),delimiter=',',encoding=None)
Out[94]: 
array([[2.02008122e+09, 2.86000000e+01],
       [2.02008122e+09, 2.47000000e+01],
       [2.02008122e+09,            nan],
       [2.02008122e+09,            nan],
       [2.02008122e+09,            nan]])
In [95]: np.genfromtxt(txt1.splitlines(),delimiter=',',encoding=None,filling_val
    ...: ues=999)
Out[95]: 
array([[2.02008122e+09, 2.86000000e+01],
       [2.02008122e+09, 2.47000000e+01],
       [2.02008122e+09, 9.99000000e+02],
       [2.02008122e+09, 9.99000000e+02],
       [2.02008122e+09, 9.99000000e+02]])

您的案例有一个特定的字符串:

In [96]: txt="""2020081217,28.6
    ...: 2020081218,24.7
    ...: 2020081219,-999.0
    ...: 2020081220,-999.0
    ...: 2020081221,-999.0"""

另一个答案建议使用 usemask,返回 masked_array:

In [100]: np.genfromtxt(txt.splitlines(),delimiter=',',encoding=None, missing_values=-999.0, usemask=True)
Out[100]: 
masked_array(
  data=[[2020081217.0, 28.6],
        [2020081218.0, 24.7],
        [2020081219.0, --],
        [2020081220.0, --],
        [2020081221.0, --]],
  mask=[[False, False],
        [False, False],
        [False,  True],
        [False,  True],
        [False,  True]],
  fill_value=1e+20)

查看代码,我推断它正在进行字符串匹配,而不是数字匹配。它也可以每列取一个值(我认为它不会进行每行测试):

In [106]: np.genfromtxt(txt.splitlines(),delimiter=',',encoding=None, 
    missing_values=['2020081217','-999.0'], usemask=True, dtype=None)
Out[106]: 
masked_array(data=[(--, 28.6), (2020081218, 24.7), (2020081219, --),
                   (2020081220, --), (2020081221, --)],
             mask=[( True, False), (False, False), (False,  True),
                   (False,  True), (False,  True)],
       fill_value=(999999, 1.e+20),
            dtype=[('f0', '<i8'), ('f1', '<f8')])

这里我给的是dtype=None,所以返回的是结构化数组

missing_values也可以是dict,但是我还没弄明白它要的是什么

我还没有想出如何让它用某些东西替换缺失值(例如来自 filling_values)。

加载后进行替换

In [110]: data = np.genfromtxt(txt.splitlines(),delimiter=',',encoding=None)
In [111]: data
Out[111]: 
array([[ 2.02008122e+09,  2.86000000e+01],
       [ 2.02008122e+09,  2.47000000e+01],
       [ 2.02008122e+09, -9.99000000e+02],
       [ 2.02008122e+09, -9.99000000e+02],
       [ 2.02008122e+09, -9.99000000e+02]])

In [114]: data[data==-999] = np.nan
In [115]: data
Out[115]: 
array([[2.02008122e+09, 2.86000000e+01],
       [2.02008122e+09, 2.47000000e+01],
       [2.02008122e+09,            nan],
       [2.02008122e+09,            nan],
       [2.02008122e+09,            nan]])

看起来 genfromtxt 从缺失值和填充值构造了一个 converters ,但我没有遵循细节。这是使用我们的转换器的一种方式

In [138]: converters={1:lambda x: np.nan if x=='-999.0' else float(x)}
In [139]: data = np.genfromtxt(txt.splitlines(),delimiter=',',encoding=None, 
    converters=converters)
In [140]: data
Out[140]: 
array([[2.02008122e+09, 2.86000000e+01],
       [2.02008122e+09, 2.47000000e+01],
       [2.02008122e+09,            nan],
       [2.02008122e+09,            nan],
       [2.02008122e+09,            nan]])