'NoneType'对象不可订阅 - 使用`np.fromregex`

时间:2016-06-01 20:30:58

标签: python numpy text-parsing

这个问题有很多答案(见Python Math - TypeError: 'NoneType' object is not subscriptable)。我的问题不同,因为我正确地期望np.genfromtxt(...)返回一个数组(即np.genfromtxt(...)不是就地函数)。

我正在尝试解析并将以下内容存储到一维数组中:

http://pastie.org/10860707#2-3

为此,我尝试了:

pattern = re.compile(b'[\s,]')
theta = np.fromregex("RegLogTheta", regexp = pattern, dtype = float)

这是追溯(如何格式化?):

Traceback (most recent call last):
File "/Users/ahanagrawal/Documents/Java/MachL/Chap3/ExamScoreVisual2.py", line    36, in <module>
theta = np.fromregex("RegLogTheta", regexp = pattern, dtype = float)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/numpy/lib/npyio.py", line 1240, in fromregex
newdtype = np.dtype(dtype[dtype.names[0]])
TypeError: 'NoneType' object is not subscriptable

如果您想运行此文件,请从以下网址下载文本文件:http://pastie.org/10860707#2-3并运行上面的代码。

1 个答案:

答案 0 :(得分:1)

该文件有多行,逗号分隔,3个数字,但最后只有2个

In [182]: fname='../Downloads/pastie-10860707.txt'

In [183]: np.fromregex(fname,regexp=pattern,dtype=float)
... 
np.fromregex(fname,regexp=pattern,dtype=float)

/usr/lib/python3/dist-packages/numpy/lib/npyio.py in fromregex(file, regexp, dtype)
   1240             # Create the new array as a single data-type and then
   1241             #   re-interpret as a single-field structured array.
-> 1242             newdtype = np.dtype(dtype[dtype.names[0]])
   1243             output = np.array(seq, dtype=newdtype)
   1244             output.dtype = dtype

TypeError: 'NoneType' object is not subscriptable

装有一个简单的&#39; br&#39;读,文件看起来像:

In [184]: txt
Out[184]: b'2.75386225e+00,1.80508078e+00,2.95729122e+00,\n-4.21413726e+00,  -3.38139076e+00,  -4.22751379e+00,\n ...      4.23010784e-01,  -1.14839331e+00,  -9.56098910e-01,\n        -1.15019836e+00,   1.13845303e-06'

最后一行丢失的号码会产生genfromtxt个问题。

您选择的模式是错误的。它看起来像一个分隔符模式。但fromregex docs中的模式会产生组:

regexp = r"(\\d+)\\s+(...)"

fromregex

seq = regexp.findall(file.read())  # read whole file and group it
output = np.array(seq, dtype=dtype)  # make array from seq

如果你想使用fromregex,你需要提出一个模式,生成一个可以直接转换为数组的元组列表。

=====

虽然再次查看错误消息,但我发现问题出在dtype上。 dtype=float不是此函数的有效dtype规范。它需要一个复合dtype(结构化)。

此操作产生错误,其中float是您的dtype参数:

In [189]: np.dtype(float).names[0]
 ...
TypeError: 'NoneType' object is not subscriptable

但是它试图这样做是因为模式产生了

In [194]: pattern.findall(txt)
Out[194]: 
[b',',
 b',',
 b',',
 b'\n',
 b',',
 b' ',
 b' ',
 ....]

不是它预期的元组列表。

==================

我可以用

加载文件
In [213]: np.genfromtxt(txt.splitlines(),delimiter=',',usecols=[0,1])
Out[213]: 
array([[  2.75386225e+00,   1.80508078e+00],
       [ -4.21413726e+00,  -3.38139076e+00],
       [  7.46991792e-01,  -1.08010066e+00],
        ...
       [  4.23010784e-01,  -1.14839331e+00],
       [ -1.15019836e+00,   1.13845303e-06]])

我使用usecols暂时解决问题,最后一行只有2个数字。

如果我删除了\n并将其拆分为逗号,我可以直接使用np.array解析生成的文本字段。

In [231]: txt1=txt.replace(b'\n',b'').split(b',')

In [232]: np.array(txt1,float)
Out[232]: 
array([  2.75386225e+00,   1.80508078e+00,   2.95729122e+00,
        -4.21413726e+00,  -3.38139076e+00,  -4.22751379e+00,
          ...
         4.23010784e-01,  -1.14839331e+00,  -9.56098910e-01,
        -1.15019836e+00,   1.13845303e-06])

此模式包括小数和科学记数法:

In [266]: pattern=re.compile(br"(\d+\.\d+e[\+\-]\d+)")

In [267]: np.fromregex(fname,regexp=pattern,dtype=np.dtype([('f0',float)]))['f0']
Out[267]: 
array([  2.75386225e+00,   1.80508078e+00,   2.95729122e+00,
         4.21413726e+00,   3.38139076e+00,   4.22751379e+00,
      ...
         4.23010784e-01,   1.14839331e+00,   9.56098910e-01,
         1.15019836e+00,   1.13845303e-06])

现在我正在创建一个结构化数组并提取该字段。可能有办法解决这个问题。但是fromregex似乎更倾向于使用结构化的dtypes。