我有一个numpy数组,其值从布尔到十进制和实数不等。我从数据库中获取这些数据,这意味着当一个字段丢失时它会返回0.我想将所有零值更改为-1,所有Falses更改为0并将Trues更改为1.但是,似乎Python无法使区分False和0,从而将两者都改为1.这就是我所尝试过的:
X[X==0] = -1
X[X==False] = 0
X[X==True] =1
结果全部为零,所有Falses都变为-1。我该如何解决这个问题?
编辑: 这是我的数组样本:
[[0.03829744 0.0 True False True True 6.0]
[0.0 0.0 True False True True 6.0]
[0.09174341 0.0 True False True True 6.0]
[0.03489284 2 0 True True False 0 6.0]]
我希望所有0.0值都为-1,所有False值为0,所有True值为1。
编辑2:循环遍历所有值,但必须有更优雅的解决方案
for i in xrange(X.shape[0]):
for j in xrange(X.shape[1]):
if X[i,j] == 0.0 and type(X[i, j]) == float:
X[i][j] = -1
答案 0 :(得分:3)
如果Numpy数组是同构的,或者至少如果它们具有与之关联的固定类型模式,则它们是最有效的。你只能在dtype=object
的numpy数组中保存你的ragtag值集合,这可能是你用numpy做的最有效的事情。
相应地,没有高效(本地numpy)方法(我知道)可以让你访问每个元素的类型。当使用numpy时,这通常不会出现。
因此,我能想到使代码更优雅的唯一方法是将双循环转换为函数调用。我将使用map
,它可能仍然没有原生numpy函数那么快(因为后者将在C中编译),但它可能比python双循环更快,更清晰同样。
然而,我在评论中也注意到了一个注意事项:您的示例数据不是矩形的,即它无法转换为2d numpy数组,无论您如何努力。我假设您在组合MCVE时犯了一个错误,并从示例数据的第四行省略了一个元素(从而使您的数组(4,7)
成形)。
import numpy as np
# dummy data as nested list, make sure it's rectangular
datlist = [[0.03829744, 0.0, True, False, True, True, 6.0],
[0.0, 0.0, True, False, True, True, 6.0],
[0.09174341, 0.0, True, False, True, True, 6.0],
[0.03489284, 0, True, True, False, 0, 6.0]] #dropped an element here
# create a numpy array of dtype object from datlist
dat = np.array(datlist,dtype=object)
我从你的例子中得知,这是你的出发点。现在,我要做的是定义一个函数来检查数组元素的值和类型,并为非bool零返回-1。然后,此函数可以map
到您的数组,利用.ravel()
访问整个数据范围:
def zeroswap(elem):
# replace non-bool zeros with -1, leave the rest alone
return -1 if elem==0 and elem is not False else elem
dat.ravel()[:] = list(map(zeroswap,dat.ravel())) #list() needed for python3
结果数组如下所示:
array([[0.03829744, -1, True, False, True, True, 6.0],
[-1, -1, True, False, True, True, 6.0],
[0.09174341, -1, True, False, True, True, 6.0],
[0.03489284, -1, True, True, False, -1, 6.0]], dtype=object)
如您所见,浮点数和整数零都已转换为-1。这对我来说是有意义的,这是因为我们只检查了非False
零。如果要区分这两种数字零,可以在zeroswap
函数中轻松完成。如果要切换bool值,也可以这样做。这是一个升级后的功能,可以转换0.0 -> -1
,0 -> -1
,False -> 0
,True -> 1
,other -> other
:
def zeroswap(elem):
if type(elem) is bool:
return int(elem)
elif elem==0:
return -1
else:
return elem
您可以将此函数调用到各种元素,以确保它能够执行您期望的操作。最重要的是,你应该map
这个功能优于阵列的分散版本,让你无需了解阵列的维度即可操作。