如何将numpy记录数组bool转换为整数以计算协方差?

时间:2012-12-10 16:54:53

标签: python numpy covariance

我有一个包含大约40个维度的大约50万个条目的记录数组。维度是数据类型的混合。我想分选5个布尔维度并获取大约1k个条目的块,然后计算协方差矩阵以查看维度相关性。我完全不知道如何使用.view().astype()来完成此转换。最初的子选择:

p_new[['no_gender', 'no_age', 'no_income', 'no_politics', 'no_edu']]
array([(False, False, True, False, False), (True, True, False, True, True),
       (True, True, False, True, True), ...,
       (True, True, True, True, True), (True, True, True, True, True),
       (True, True, True, True, True)], 
      dtype=[('no_gender', '|b1'), ('no_age', '|b1'), ('no_income', '|b1'), ('no_politics', '|b1'), ('no_edu', '|b1')])

我的所有转换尝试都会将我的5个维度折叠为1(不需要的!),因此我不会从(1000,5) dtype=np.bool转到(1000,5) dtype=np.int32,而是以(1000,1) dtype=np.int32结束。

4 个答案:

答案 0 :(得分:1)

实际上你根本不需要将布尔值转换为整数。在Python中,TrueFalse实际上是int的子类,因此您可以像往常一样对它们执行所有数学运算。 True1False0

证明:

>>> isinstance(True, int)
True
>>> isinstance(False, int)
True
>>> (True + True * 3) / (True + False)
4

虽然我会承认,但我并不是100%确定numpy数据类型,以及这可能与您尝试做的事情有关。

更新

更多地研究numpy数据类型,它们似乎表现出相似但不相同的行为。 numpy.bool字面上与bool相同,它只是标准的Python布尔值,所以它绝对表现出所有相同的行为,可以用作整数。但是,numpy.int32int的单独子类,因此isinstance(numpy.bool(1), numpy.int32)自然会评估为False。也许你直接进入int / numpy.int可以减少麻烦?

答案 1 :(得分:1)

我猜你的问题是当你改变类型时你在整行上操作。 如果您以bool数组的形式查看,则会获得所有值,然后您可以执行astype。但是你必须重新塑造。

pnew.view("bool").astype(int).reshape(len(pnew),-1)

更容易使用.tolist(),但可能会使用更多内存,可能会更慢。

asarray(pnew.tolist()).astype(int)

答案 2 :(得分:1)

请注意,在重新排列中,每条记录都被视为单个元素,即对于以下数组,形状为(3),而不是(3,5)。

A = np.array([('joe', 44, True, True, False),
              ('jill', 22, False, False, False),
              ('Jack', 21, True, False, True)],
             dtype=[['name', 'S4'], ['age', int], ['x', bool],
                    ['y', bool], ['z', bool]])
print A.shape
# (3,)

做出你所要求的最简单的方法可能是:

tmp = [A[field] for field in ['x', 'y', 'z']]
tmp = np.array(tmp, dtype=int)

您也可以使用视图,但对具有混合数据类型的数组使用视图会有点棘手。

答案 3 :(得分:1)

您可以创建新的dtype,而不是使用a.astype(new_dtype)

In [44]: a
Out[44]: 
array([(False, False, True, False, False), (True, True, False, True, True),
       (True, True, False, True, True), (True, True, True, True, True),
       (True, True, True, True, True), (True, True, True, True, True)], 
      dtype=[('no_gender', '|b1'), ('no_age', '|b1'), 
             ('no_income', '|b1'), ('no_politics', '|b1'), ('no_edu', '|b1')])

In [45]: new_dtype = np.dtype([(name, np.int) for name in a.dtype.names])

In [46]: a.astype(new_dtype)
Out[46]: 
array([(0, 0, 1, 0, 0), (1, 1, 0, 1, 1), (1, 1, 0, 1, 1), (1, 1, 1, 1, 1),
       (1, 1, 1, 1, 1), (1, 1, 1, 1, 1)], 
      dtype=[('no_gender', '<i8'), ('no_age', '<i8'), ('no_income', '<i8'),
             ('no_politics', '<i8'), ('no_edu', '<i8')])