将带括号的字符串转换为numpy数组

6

问题描述:

我在一个数据框的列中读取了一个类似于数组的结构,其格式为字符串(从CSV文件中读取数据)。

该列中的一个字符串元素如下所示:

In  [1]: df.iloc[0]['points']    
Out [2]: '[(-0.0426, -0.7231, -0.4207), (0.2116, -0.1733, -0.1013), (...)]'

所以它真的是一个类似于数组的结构,对我来说看起来“准备好了用于numpy”。

numpy.fromstring() 无法帮助您,因为它不喜欢括号:
将数组的字符串表示转换为Python中的numpy数组

如果我将其复制并粘贴到array()函数中,则仅对字符串执行简单的numpy.array()会返回一个numpy数组。
但是,如果我像这样使用包含字符串的变量填充array()函数:np.array(df.iloc[0]['points'])它就不起作用,并给出ValueError:could not convert string to float错误信息。

将字符串转换为numpy数组

问题:

是否有任何可以简单完成此操作的函数(而不是替换或使用正则表达式去掉括号)?


第一个问题是:这些数据来自哪里?是你生成的吗?还是由某个程序或库生成的?如果你可以修复数据,使其以实际可解析的形式创建,或者至少找到关于格式和如何使用它的确切说明,那将比通过猜测进行反向工程并编写一个不完善的解析器要好得多。 - abarnert
无论如何,这看起来像是有人将元组列表的repr写入文件。这是一个非常糟糕的想法,但如果你不能改变它,你可以通过在每个字符串上调用ast.literal_eval来反转它。这将适用于您发布的示例,但不能保证它将适用于您所有的数据,或者您不会遇到浮点舍入问题,这些问题在正确序列化的数据中不存在。这只是一个hack,而不是解决方案。 - abarnert
“structured”数组的字符串(print)表示形式是元组列表。repr字符串将包括dtype信息。但由于这是DataFrame中的单元格,可能还有其他可能性。您是从csv文件加载此df吗?该文件中是否有像这样的引号字符串? - hpaulj
1个回答

10
你可以在传递给numpy.array之前使用ast.literal_eval:
from ast import literal_eval
import numpy as np

x = '[(-0.0426, -0.7231, -0.4207), (0.2116, -0.1733, -0.1013)]'

res = np.array(literal_eval(x))

print(res)

array([[-0.0426, -0.7231, -0.4207],
       [ 0.2116, -0.1733, -0.1013]])

您可以使用 Pandas series 中的字符串完成相应操作,但不清楚是否需要跨行聚合。如果是这种情况,您可以使用上述逻辑派生出的 NumPy 数组列表进行组合。
文档解释了 literal_eval 可接受的类型:
安全地计算表达式节点或包含Python文字/容器展示的字符串。提供的字符串或节点只能由以下Python文字结构组成:字符串、字节、数字、元组、列表、字典、集合、布尔和 None
因此,我们实际上将字符串转换为元组列表,然后 np.array 可以将其转换为 NumPy 数组。

1
太棒了!我不知道这个模块! - swiss_knight
1
literal_eval正在解析看起来像元组列表的字符串。它处理基本的Python结构。JSON也做类似的事情,但是针对更受限制的语法。 - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接