如何在Python中将布尔数组转换为整数数组

18

我有一个Numpy的二维数组,其中一列是布尔值,即True/False。 我想将其分别转换为整数10,该如何做?

例如,我的data[0::,2] 是布尔值,我尝试了:

data[0::,2]=int(data[0::,2])

但是它给了我一个错误:

TypeError: 只有长度为1的数组可以转换为Python标量

我的前五行数组是:

[['0', '3', 'True', '22', '1', '0', '7.25', '0'],
 ['1', '1', 'False', '38', '1', '0', '71.2833', '1'],
 ['1', '3', 'False', '26', '0', '0', '7.925', '0'],
 ['1', '1', 'False', '35', '1', '0', '53.1', '0'],
 ['0', '3', 'True', '35', '0', '0', '8.05', '0']]

3
这似乎不是一个二维数组,因为在二维数组中,所有元素都具有相同的类型。可能是一个结构化数组。您能否展示一些完整的行以及它的“dtype”? - kirelagin
1
好的,这些引号应该提示您有一个字符串数组。因此,在numpy中,2D数组的所有元素都必须具有相同的类型。您可以使用结构化数组,或者只需摆脱numpy并使用普通的Python列表。您为什么需要numpy,您的最终目标是什么? - kirelagin
1
实际上,我正在跟随一个使用Python的机器学习项目教程,由于我对Python不熟悉,所以遇到了一些困难。它要求使用NumPy数组。如果您能告诉我如何将整个字符串数组转换为浮点数,那就太好了,因为很明显可以将其转换为浮点数(将true视为1,false视为0)。 - Akashdeep Saluja
1
你是如何产生数据的呢?从文本文件中获取吗? - root
5个回答

22

好的,将任何数组类型更改为浮点数最简单的方法是执行:

data.astype(float)

您的数组问题在于,float('True')是一个错误,因为'True'无法解析为浮点数。所以,最好的方法是修复您的数组生成代码以生成浮点数(或至少是具有有效浮点数字面值的字符串),而不是布尔值。

与此同时,您可以使用此函数来修复您的数组:

def boolstr_to_floatstr(v):
    if v == 'True':
        return '1'
    elif v == 'False':
        return '0'
    else:
        return v

最后,您可以像这样转换数组:

new_data = np.vectorize(boolstr_to_floatstr)(data).astype(float)

@AkashdeepSaluja 我已经仔细检查了代码,它对我来说是有效的。你能否更新你的问题,提供 data[:5] 的确切输出? - kirelagin
问题中的输出是确切的输出,您需要其他的吗? - Akashdeep Saluja
@AkashdeepSaluja 不,这不可能是真的。首先,我在问题中看到的不是numpy数组,而是Python列表。在我编辑之前,缺少了逗号- Python无法输出此内容。其次,我的代码也适用于Python列表,所以一切都应该没问题。将print(data[:5])添加到您的代码中,并发布确切的输出。 - kirelagin
甚至更好的做法是使用 from pprint import pprint,然后使用 pprint(data[:5]) - kirelagin

14

boolarrayvariable.astype(int) 能够起作用:

data = np.random.normal(0,1,(1,5))
threshold = 0
test1 = (data>threshold)
test2 = test1.astype(int)

输出:

data = array([[ 1.766, -1.765,  2.576, -1.469,  1.69]])
test1 = array([[ True, False,  True, False,  True]], dtype=bool)
test2 = array([[1, 0, 1, 0, 1]])

2
如果我在您的原始数据源上执行此操作,该数据源是字符串:
data = [['0', '3', 'True', '22', '1', '0', '7.25', '0'],
        ['1', '1', 'False', '38', '1', '0', '71.2833', '1'],
        ['1', '3', 'False', '26', '0', '0', '7.925', '0'],
        ['1', '1', 'False', '35', '1', '0', '53.1', '0'],
        ['0', '3', 'True', '35', '0', '0', '8.05', '0']]

data = [[eval(x) for x in y] for y in data]

...然后跟着这个:

data = [[float(x) for x in y] for y in data]
# or this if you prefer:
arr = numpy.array(data)

然后问题就解决了。你甚至可以将其作为一行代码执行(我认为这会生成整数,但可能需要浮点数):numpy.array([[eval(x) for x in y] for y in data])

我认为问题在于numpy将数字字符串保留为字符串,并且由于并非所有字符串都是数字,您无法对整个数组进行类型转换。此外,如果您尝试仅对具有“True”和“False”的数组部分进行类型转换,则实际上并不使用布尔值,而是使用字符串。..而我知道改变这种情况的唯一方法是执行eval语句。..好吧,你也可以这样做:

booltext_int = {'True': 1, 'False': 2}
clean = [[float(x) if x[-1].isdigit() else booltext_int[x]
          for x in y] for y in data]

这样可以避免使用eval,因为它本质上是不安全的。但如果您使用的是可信数据源,则可能并不重要。


1
使用 @kirelagin 的想法,结合 ast.literal_eval
>>> import ast
>>> import numpy as np
>>> arr = np.array(
        [['0', '3', 'True', '22', '1', '0', '7.25', '0'],
        ['1', '1', 'False', '38', '1', '0', '71.2833', '1'],
        ['1', '3', 'False', '26', '0', '0', '7.925', '0'],
        ['1', '1', 'False', '35', '1', '0', '53.1', '0'],
        ['0', '3', 'True', '35', '0', '0', '8.05', '0']])
>>> np.vectorize(ast.literal_eval, otypes=[np.float])(arr)
array([[  0.    ,   3.    ,   1.    ,  22.    ,   1.    ,   0.    ,
          7.25  ,   0.    ],
       [  1.    ,   1.    ,   0.    ,  38.    ,   1.    ,   0.    ,
         71.2833,   1.    ],
       [  1.    ,   3.    ,   0.    ,  26.    ,   0.    ,   0.    ,
          7.925 ,   0.    ],
       [  1.    ,   1.    ,   0.    ,  35.    ,   1.    ,   0.    ,
         53.1   ,   0.    ],
       [  0.    ,   3.    ,   1.    ,  35.    ,   0.    ,   0.    ,
          8.05  ,   0.    ]])

0

虽然这是一个老问题,但是作为参考 - 布尔值可以转换为整数,整数可以转换为浮点数。

data[0::,2]=data[0::,2].astype(int).astype(float)


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