非字母复数的字符串转为numpy数组

我想拿一条这样的线

A = '[[complex(1,-1), complex(1,1)], [1, 1]]'

并将其转换为这个numpy数组

array([[1.-1.j, 1.+1.j],
   [1.+0.j, 1.+0.j]])

我试着用这个代码

string = a.replace("[","").replace("]","").replace("\"",  "").replace(" ","")
np.fromstring(string, dtype=complex, count=-1, sep=',')

但输出是这样的

array([], dtype=complex128)

如果至少有一个简单的方法可以把矩阵A写成这样的形式。

A = '1-1j, 1+1j, 1, 1'

上面的代码工作。我需要对大量从.csv导入的矩阵进行处理。

解决方案:

我们必须抵制住使用 eval因为 eval 是不安全的,也是不好的做法. 它 真的很危险. 如果你能确定输入是安全的,因为你正在控制输入:改变上一步的输出,这样你就不必使用 eval 摆在首位。

由于您的用例非常具体(complex(a, b) 其中既不 a 也不 b 可以包含任何逗号或括号),很容易写出一个regex模式,以帮助用复杂的字元替换复杂的调用。一旦我们有了这样的模式,我们就可以使用 ast.literal_eval 执行 安全的 从字符串到数字的转换,你可以将其输入numpy。

请看下面几个定义。

import ast
import re

pattern = re.compile(r'complex\(([^)]+),([^)]+)\)') 

def complex_from_match(match): 
    """Converts a regex match containing 'complex(a, b)' to a complex number""" 
    re = float(match.group(1)) 
    im = float(match.group(2)) 
    return re + 1j*im 

def literalify_complex(s): 
    """Converts a string with a number of the form complex(a, b) into a string literal"""

    return pattern.sub(lambda match: repr(complex_from_match(match)), s)

这里 pattern 是一个符合以下形式的子串的regex模式。complex(a, b). 对于每场比赛 match.group(1) 给我们 amatch.group(2) 给予 b.

该功能 literalify_complex(s) 电话 pattern.sub 在输入字符串上 s,它将在每次匹配模式时调用传递的可调用(lambda)。patterns. 我定义的lambda使用的是 complex_from_match 函数,它将匹配的字符串 complex(a,b) 并有效地将其转化为原生的python复数。a + 1j*b. 然后将这个复数转换成它的 repr 在更换过程中,有效地将诸如 complex(1, 3.4) 变成 1+3.4j. 下面是输出结果的样子。

>>> literalify_complex('[[complex(1,-1), complex(1,1)], [1, 1]]')
'[[(1-1j), (1+1j)], [1, 1]]'

>>> literalify_complex('[[complex(0,-3.14), complex(1.57337537832783243243,1e-100)], [1, 1]]')
'[[-3.14j, (1.5733753783278324+1e-100j)], [1, 1]]'

现在这些字符串可以直接转换为嵌套的python列表,使用 literal_eval:

>>> ast.literal_eval(literalify_complex('[[complex(1,-1), complex(1,1)], [1, 1]]'))
[[(1-1j), (1+1j)], [1, 1]]

然后这些列表可以传递给numpy。

def crazy_complex_string_to_ndarray(s): 
    return np.array(ast.literal_eval(literalify_complex(s)))

# >>> crazy_complex_string_to_ndarray('[[complex(1,-1), complex(1,1)], [1, 1]]')
# array([[1.-1.j, 1.+1.j],
#        [1.+0.j, 1.+0.j]])
#
# >>> crazy_complex_string_to_ndarray('[[complex(0,-3.14),  complex(1.57337537832783243243,1e-100)], [1, 1]]')
# array([[-0.        -3.14e+000j,  1.57337538+1.00e-100j],
#        [ 1.        +0.00e+000j,  1.        +0.00e+000j]])

这种方法的好处是,任何形式的畸形或恶意输入都会响亮地失败(在输入过程中)。ast.literal_eval 步),而不是给人意想不到或有害的结果。

给TA打赏
共{{data.count}}人
人已打赏
未分类

Java Android,循环浏览所有的获取者

2022-9-9 4:13:18

未分类

如果两个字符串的长度不一样,如何用core python 3逐个连接字符?

2022-9-9 4:13:20

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索