以下是比@Jeff的回答更为直接的方法,使用辅助函数parse_pair
将(1.2,0.16)
映射到1.20+0.16j
,以复数数组的形式直接加载到loadtxt
中:
>>> import re
>>> import numpy as np
>>> pair = re.compile(r'\(([^,\)]+),([^,\)]+)\)')
>>> def parse_pair(s):
... return complex(*map(float, pair.match(s).groups()))
>>> s = '''1 (1.2,0.16) (2.8,1.1)
2 (2.85,6.9) (5.8,2.2)'''
>>> from cStringIO import StringIO
>>> f = StringIO(s)
>>> np.loadtxt(f, delimiter=' ', dtype=np.complex,
... converters={1: parse_pair, 2: parse_pair})
array([[ 1.00+0.j , 1.20+0.16j, 2.80+1.1j ],
[ 2.00+0.j , 2.85+6.9j , 5.80+2.2j ]])
或者在pandas中:
>>> import pandas as pd
>>> f.seek(0)
>>> pd.read_csv(f, delimiter=' ', index_col=0, names=['a', 'b'],
... converters={1: parse_pair, 2: parse_pair})
a b
1 (1.2+0.16j) (2.8+1.1j)
2 (2.85+6.9j) (5.8+2.2j)
complex(b'1')
失败并引发了TypeError
,而float(b'1')
却可以正常工作。这应该是使用loadtxt(..., dtype=complex)
读取任何内容时都会遇到的问题;您可以通过添加一个转换器来解决其他所有问题,例如lambda x: complex(x.decode() if isinstance(x, bytes) else x)
。parse_pair
还需要对其输入进行解码,以便将其与正则表达式匹配。真是令人烦恼... - Danicaparse_pair
来尝试您的解决方案。 - Joey Dumonts.decode()
替换pair.match(s)
即可。不过这样做不会给你带来错误;尝试将{0: lambda x: complex(x.decode())}
添加到converters
字典中? - Danica