Python ndarray转行 ndarray转int_python 将数据改为int型


我们了解了如何使用索引进行切片以及选择 ndarray 元素。当我们知道要选择的元素的确切索引时,这些方法很有用。但是,在很多情况下,我们不知道要选择的元素的索引。例如,假设有一个 10,000 x 10,000 ndarray,其中包含从 1 到 15,000 的随机整数,我们只想选择小于 20 的整数。这时候就要用到布尔型索引。

来看这样一个例子,假设我们有一个用于存储数据的数组以及一个存储姓名的数组(含有重复项)。在这里,我将使用numpy.random中的randn函数生成一些正态分布的随机数据:


names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data =np.random.randn(7,4)
data

out
array([[-0.53447574,  0.44543995,  0.20598584,  1.08783591],
       [-0.77863291,  0.19012144, -0.57628278,  2.21230602],
       [-1.94785822,  1.75829325,  0.76416317, -0.26749686],
       [ 1.55128542, -0.48229173, -0.10775036,  1.82210628],
       [-0.75344013,  1.49328631,  0.19576227, -1.37773471],
       [-0.28998065, -0.54219643,  0.44587161, -1.17333163],
       [ 2.28372601,  0.9102604 , -0.15811983,  1.16763758]])


假设每个名字都对应data数组中的一行,而我们想要选出对应于名字"Bob"的所有行。跟算术运算一样,数组的比较运算(如==)也是矢量化的。因此,对names和字符串"Bob"的比较运算将会产生一个布尔型数组:


names == "Bob"

out
array([ True, False, False,  True, False, False, False])

********************************************************

data[names =='Bob'] #True为选择,False为不选择

out
array([[7., 7., 7., 7.],
       [7., 7., 7., 7.]])


布尔型数组的长度必须跟被索引的轴长度一致。此外,还可以将布尔型数组跟切片、整数(或整数序列,稍后将对此进行详细讲解)混合使用:


data[names == 'Bob']

out
array([[-1.33599022,  0.04700321,  0.98537189,  0.33183721],
       [-0.2225323 ,  0.10320653,  1.24636372, -0.38496333]])


注意:如果布尔型数组的长度不对,布尔型选择就会出错,因此一定要小心。

下面的例子,我选取了names == 'Bob'的行,并索引了列:


data[names == 'Bob', 2:]
 
 out
 array([[ 0.98537189,  0.33183721],
       [ 1.24636372, -0.38496333]])

 ********************************************************
  data[names == 'Bob', 3]
  
  out


要选择除"Bob"以外的其他值,既可以使用不等于符号(!=),也可以通过~对条件进行否定:


names   != "Bob"

out
array([False,  True,  True, False,  True,  True,  True])

 ********************************************************

data[~(names == 'Bob')]

out
array([[ 0.04813526,  0.481971  , -0.23318465, -0.08770203],
       [ 2.39572745, -0.03834795, -0.49294046, -0.76124253],
       [-0.30962763,  0.3454903 ,  0.30120547,  0.82999187],
       [-1.46354427, -1.00491798,  0.4574028 ,  1.26923957],
       [ 0.46142634,  1.55466835, -0.54772161, -0.65769753]])


~操作符用来反转条件很好用


cond = names == 'Bob'
data[~cond]

out
array([[ 0.04813526,  0.481971  , -0.23318465, -0.08770203],
       [ 2.39572745, -0.03834795, -0.49294046, -0.76124253],
       [-0.30962763,  0.3454903 ,  0.30120547,  0.82999187],
       [-1.46354427, -1.00491798,  0.4574028 ,  1.26923957],
       [ 0.46142634,  1.55466835, -0.54772161, -0.65769753]])


选取这三个名字中的两个需要组合应用多个布尔条件,使用&(和)、|(或)之类的布尔算术运算符即可:


mask = (names == "Bob") | (names == "Will" )
mask

out
array([ True, False,  True,  True,  True, False, False])

 ********************************************************
data[mask]

out

array([[-1.33599022,  0.04700321,  0.98537189,  0.33183721],
       [ 2.39572745, -0.03834795, -0.49294046, -0.76124253],
       [-0.2225323 ,  0.10320653,  1.24636372, -0.38496333],
       [-0.30962763,  0.3454903 ,  0.30120547,  0.82999187]])


通过布尔型索引选取数组中的数据,将总是创建数据的副本,即使返回一模一样的数组也是如此。

注意:Python关键字and和or在布尔型数组中无效。要使用&与|。

通过布尔型数组设置值是一种经常用到的手段。为了将data中的所有负值都设置为0,我们只需:


data[data < 0] = 0
data

out
array([[0.        , 0.04700321, 0.98537189, 0.33183721],
       [0.04813526, 0.481971  , 0.        , 0.        ],
       [2.39572745, 0.        , 0.        , 0.        ],
       [0.        , 0.10320653, 1.24636372, 0.        ],
       [0.        , 0.3454903 , 0.30120547, 0.82999187],
       [0.        , 0.        , 0.4574028 , 1.26923957],
       [0.46142634, 1.55466835, 0.        , 0.        ]])


通过一维布尔数组设置整行或列的值也很简单:


data[names != 'Joe'] = 7
data

out
array([[7.        , 7.        , 7.        , 7.        ],
       [0.04813526, 0.481971  , 0.        , 0.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [0.        , 0.        , 0.4574028 , 1.26923957],
       [0.46142634, 1.55466835, 0.        , 0.        ]])


后面会看到,这类二维数据的操作也可以用pandas方便的来做。