Python 将复杂数据读入numpy数组
我需要将文本文件中的复数读入numpy数组。我的问题与此类似,但是,这里的解决方案是更改数据保存的格式。我没有这种奢侈,因为文本文件是由其他软件生成的,我无法更改。文本文件的示例如下所示:Python 将复杂数据读入numpy数组,python,numpy,Python,Numpy,我需要将文本文件中的复数读入numpy数组。我的问题与此类似,但是,这里的解决方案是更改数据保存的格式。我没有这种奢侈,因为文本文件是由其他软件生成的,我无法更改。文本文件的示例如下所示: 25 + 0i 8.43818 + -4.94194i 4.46817 + -5.08305i 4.55764 + -3.02201i 2.69138 + -5.43104i -0.151334 + -4.83717i 1.98336 + -1.3339i 3.59002 + -0.932973i 1.427
25 + 0i
8.43818 + -4.94194i
4.46817 + -5.08305i
4.55764 + -3.02201i
2.69138 + -5.43104i
-0.151334 + -4.83717i
1.98336 + -1.3339i
3.59002 + -0.932973i
1.42727 + -0.617317i
1.02005 + -1.14214i
-0.15564 + 2.74564i
我尝试了以下方法:
np.loadtxt('file.txt',delimiter='\n',dtype=np.complex128)
但是我得到了一个错误:
ValueError: complex() arg is a malformed string
我读过的帖子表明,这是某些行中的+-
符号的问题,但是,即使删除了额外的+
符号,我也会遇到同样的错误
然而,这里的解决方案是改变数据保存的格式
好消息,你不必这么做
numpy.loadtxt
可以接受任意一行,而不仅仅是一个文件对象
因此,您可以将文件对象包装在一个简单的生成器中,该生成器可以动态地转换行,并将其提供给loadtxt
,每个人都会很高兴
像这样:
def transform_complex(line):
# insert your code here
with open('file.txt', 'rb') as f:
lines = map(transform_complex, f)
arr = np.loadtxt(lines, dtype=np.complex128)
(如果您使用的是Python2.x,并且文件很大,那么您可能希望使用itertools.imap
而不是map
)
“在此处插入您的代码”部分,您根据有效的答案填写,但这不是一个可接受的解决方案,因为它需要修改文件。由于我在您的链接中没有看到这样的答案,我不确定这是什么,但例如,可能是这样的:
def transform_complex(line):
return line.replace(b'+ -', b'- ')
在本地进行测试时,看起来您的输入实际上有三个错误 您可以使用
savetxt
测试输出的外观。例如:
>>> arr = np.array([1-2j])
>>> f = io.BytesIO()
>>> np.savetxt(f, arr)
>>> f.getvalue()
b' (1.000000000000000000e+00-2.000000000000000000e+00j)\n'
(在Python2.x中,您将看不到b
前缀。)
并非所有这些差异都是相关的——你不必使用指数表示法,你不需要帕伦等——但看起来这三个是:
周围不允许有复数空格+
- 虚单位必须是
,而不是j
i
- 不允许使用
+-
@abarnert的回答很好,但是不要忘记,
loadtxt
有一个参数,converters
,
它提供了一个钩子,用于自定义字段的处理方式。这里有一对
演示如何使用它处理此文件的示例
在第一个版本中,保留默认分隔符(空白),
所以有三列。
usecols
用于忽略中间的列(“+”)。转换器用于
将最后一列(第2列)转换为浮点值。它使用一个切片来丢弃
最后一个字符,即“i”。使用这些参数,loadtxt
返回一个数组
具有浮点值的形状(11,2)。通过使用
键入np.complex128
,数组将转换为浮点值数组
具有形状(11,1)。最后,使用[:,0]
索引给出了复杂值的1D数组。
(可以使用调用ravel
、挤压
或重塑
)
下一个版本将整行视为单个字段。以下函数
将文件中使用格式的字符串转换为复数:
In [36]: def to_complex(field):
....: return complex(field.replace(' ', '').replace('+-', '-').replace('i', 'j'))
....:
In [37]: loadtxt('file.txt', converters={0: to_complex}, dtype=np.complex128, delimiter=';')
Out[37]:
array([ 25.000000+0.j , 8.438180-4.94194j , 4.468170-5.08305j ,
4.557640-3.02201j , 2.691380-5.43104j , -0.151334-4.83717j ,
1.983360-1.3339j , 3.590020-0.932973j, 1.427270-0.617317j,
1.020050-1.14214j , -0.155640+2.74564j ])
例如
对loadtxt
的调用将每一行视为一个字段,并使用
将每个字段转换为复数的转换器:
In [36]: def to_complex(field):
....: return complex(field.replace(' ', '').replace('+-', '-').replace('i', 'j'))
....:
In [37]: loadtxt('file.txt', converters={0: to_complex}, dtype=np.complex128, delimiter=';')
Out[37]:
array([ 25.000000+0.j , 8.438180-4.94194j , 4.468170-5.08305j ,
4.557640-3.02201j , 2.691380-5.43104j , -0.151334-4.83717j ,
1.983360-1.3339j , 3.590020-0.932973j, 1.427270-0.617317j,
1.020050-1.14214j , -0.155640+2.74564j ])
(分隔符设置为;”
,但它可能是
不会出现在文件中。)
In [37]: loadtxt('file.txt', converters={0: to_complex}, dtype=np.complex128, delimiter=';')
Out[37]:
array([ 25.000000+0.j , 8.438180-4.94194j , 4.468170-5.08305j ,
4.557640-3.02201j , 2.691380-5.43104j , -0.151334-4.83717j ,
1.983360-1.3339j , 3.590020-0.932973j, 1.427270-0.617317j,
1.020050-1.14214j , -0.155640+2.74564j ])