numpy基础

1.1 numpy 的 ndarray

import numpy as np
data = np.random.randn(2,3) #随机2*3矩阵
print(data.shape,data.dtype)  #shape是表示矩阵各维度大小的元组,dtype则表示矩阵内部各元素的类型。

#(2, 3) float64

1.1.1创建ndarray

创建数组最简单的办法就是使用array函数

data1=[1,2,3,4]
arr1=np.array(data1)
data2=[[1,2,3,4],[5,6,7,8]]
arr2=np.array(data2)

print(arr2.ndim)#获取arr2的维度,显然是2,

np.array会尝试为新建的这个数组推断出一个较为合适的数据类型。数据类型保存在一个特殊的dtype对象中。

除np.array之外,还有一些函数也可以新建数组。比如,zeros和ones分别可以创建指定长度或形状的全0或全1数组。empty可以创建一个没有任何具体值的数组。要用这些方法创建多维数组,只需传入一个表示形状的元组即可:

arange是Python内置函数range的数组版

print(np.arange(15))

[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]

1.1.2 ndarray的数据类型

dtype(数据类型)是一个特殊的对象,它含有ndarray将一块内存解释为特定数据类型所需的信息:

arr1 = np.array([1, 2, 3], dtype=np.float64)

arr2 = np.array([1, 2, 3], dtype=np.int32)

可以通过ndarray的astype方法明确地将一个数组从一个dtype转换成另一个dtype

arr = np.array([1, 2, 3, 4, 5])
float_arr = arr.astype(np.float64) 

如果某字符串数组表示的全是数字,也可以用astype将其转换为数值形式:

numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
print(numeric_strings.astype(float))  #[1.25,-9.6,42]
使用numpy.string_类型时,一定要小心,因为NumPy的字符串数据是大小固定的,发生截取时,不会发出警告。pandas提供了更多非数值数据的便利的处理方法。

1.1.3 numpy数组运算

数组与标量的算术运算会将标量值传播到各个元素,大小相同的数组之间的比较会生成布尔值数组

arr = np.array([[1., 2., 3.], [4., 5., 6.]])
print(arr)
print(arr * arr)
print(arr - arr)
print(1 / arr)
print(arr ** 0.5)
arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
print(arr2)
print(arr2 > arr)

[[ 1.  2.  3.]
 [ 4.  5.  6.]]
[[  1.   4.   9.]
 [ 16.  25.  36.]]
[[ 0.  0.  0.]
 [ 0.  0.  0.]]
[[ 1.          0.5         0.33333333]
 [ 0.25        0.2         0.16666667]]
[[ 1.          1.41421356  1.73205081]
 [ 2.          2.23606798  2.44948974]]
[[  0.   4.   1.]
 [  7.   2.  12.]]
[[False  True False]
 [ True False  True]]

1.1.4数组的广播

如果两个数组的维数不相同,则元素到元素的操作是不可能的。 然而,在 NumPy 中仍然可以对形状不相似的数组进行操作,因为它拥有广播功能。 较小的数组会广播到较大数组的大小,以便使它们的形状可兼容。

如果满足以下规则,可以进行广播:

  • ndim较小的数组会在前面追加一个长度为 1 的维度。
  • 输出数组的每个维度的大小是输入数组该维度大小的最大值。
  • 如果输入在每个维度中的大小与输出大小匹配,或其值正好为 1,则可以在计算中使用该输入。
  • 如果输入的某个维度大小为 1,则该维度中的第一个数据元素将用于该维度的所有计算。

如果上述规则产生有效结果,并且满足以下条件之一,那么数组被称为可广播的。

  • 数组拥有相同形状。
  • 数组拥有相同的维数,每个维度拥有相同长度,或者长度为 1。
  • 数组拥有极少的维度,可以在其前面追加长度为 1 的维度,使上述条件成立。

import numpy as np
a = np.array([[0.0,0.0,0.0],[10.0,10.0,10.0],[20.0,20.0,20.0],[30.0,30.0,30.0]])
b = np.array([1.0,2.0,3.0])
print ('第一个数组:')
print (a)
print ('\n第二个数组:')
print (b)
print ('\n第一个数组加第二个数组:')
print (a + b)

第一个数组:
[[  0.   0.   0.]
 [ 10.  10.  10.]
 [ 20.  20.  20.]
 [ 30.  30.  30.]]

第二个数组:
[ 1.  2.  3.]

第一个数组加第二个数组:
[[  1.   2.   3.]
 [ 11.  12.  13.]
 [ 21.  22.  23.]
 [ 31.  32.  33.]]

1.1.5数组的索引和切片

当你将一个标量值赋值给一个切片时(如arr[5:8]=12),该值会自动传播到整个选区。跟列表最重要的区别在于,数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。

arr = np.arange(10)
print (arr)
#arr的第6个元素
print (arr[5])
#arr的第6-8个元素,[5:8]左闭右开
print (arr[5:8])
arr[5:8] = 12
print (arr)
[0 1 2 3 4 5 6 7 8 9]
5
[5 6 7]
[ 0  1  2  3  4 12 12 12  8  9]

改变arr_slice中的值,变动也会体现在原始数组arr中:

arr_slice[1] = 12345
print (arr)
[    0     1     2     3     4    12 12345    12     8     9]

切片[ : ]会给数组中的所有值赋值:

arr_slice[:] = 64
print (arr)
[ 0  1  2  3  4 64 64 64  8  9]

如果你想要得到的是ndarray切片的一份副本而非视图,就需要明确地进行复制操作,例如arr[5:8].copy()

对于高维度数组,能做的事情更多。在一个二维数组中,各索引位置上的元素不再是标量而是一维数组:

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2d[2])
[7 8 9]

可以对各个元素进行递归访问,但这样需要做的事情有点多。你可以传入一个以逗号隔开的索引列表来选取单个元素。也就是说,下面两种方式是等价的:

print (arr2d[0][2])  #3
print (arr2d[0, 2])  #3

在多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray(它含有高一级维度上的所有数据)。因此,在2×2×3数组arr3d中:

arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr3d)
[[[ 1  2  3]
  [ 4  5  6]]

 [[ 7  8  9]
  [10 11 12]]]
print(arr3d[0])
[[1 2 3]
 [4 5 6]]

标量值和数组都可以被赋值给arr3d[0]:

#将arr3d[0]的数据进行备份
old_values = arr3d[0].copy()
#修改arr3d[0]的值为42
arr3d[0] = 42
print(arr3d)
print('===========分割线============')
arr3d[0] = old_values
print(arr3d)
[[[42 42 42]
  [42 42 42]]

 [[ 7  8  9]
  [10 11 12]]]
===========分割线============
[[[ 1  2  3]
  [ 4  5  6]]

 [[ 7  8  9]
  [10 11 12]]]
print (arr3d[1, 0])
print('===========分割线============')
x = arr3d[1]
print (x)
print (x[0])
[7 8 9]
===========分割线============
[[ 7  8  9]
 [10 11 12]]
[7 8 9]

1.1.6切片索引

ndarray的切片语法跟Python列表这样的一维对象差不多:

arr = np.array([[1., 2., 3.], [4., 5., 6.],[7,8,9]])
print(arr[:2])

[[ 1.  2.  3.]
 [ 4.  5.  6.]]

可以看出,它是沿着第0轴(即第一个轴)切片的。也就是说,切片是沿着一个轴向选取元素的。表达式arr2d[:2]可以被认为是“选取arr2d的前两行”。

你可以一次传入多个切片,就像传入多个索引那样:

print(arr2d[:2, 1:])
[[2 3]
 [5 6]]

1.1.7 布尔型索引

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

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = np.random.randn(7, 4)
print(names)
print(data)
['Bob' 'Joe' 'Will' 'Bob' 'Will' 'Joe' 'Joe']
[[ 0.65351776  0.05222893  0.90505454  0.7626202 ]
 [ 0.30115436 -0.22774645  0.86443034  1.60146854]
 [-1.63004358  0.04772191 -0.22369828  0.7149201 ]
 [ 0.79504143 -1.44998811 -1.78426926  0.76580967]
 [-0.5974943  -0.64096068  0.39920987  0.04074823]
 [ 0.38440422  1.46278306 -1.41673059  0.27833875]
 [-0.76145106 -0.4296969   1.35222181  1.60042572]]

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

print(names == 'Bob')
[ True False False  True False False False]
print(data[names == 'Bob'])
[[ 0.65351776  0.05222893  0.90505454  0.7626202 ]
 [ 0.79504143 -1.44998811 -1.78426926  0.76580967]]

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

print(data[names == 'Bob', 2:])
print('===========分割线============')
print(data[names == 'Bob', 3])
[[ 0.90505454  0.7626202 ]
 [-1.78426926  0.76580967]]
===========分割线============
[ 0.7626202   0.76580967]

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

print(names != 'Bob')
print(data[~(names == 'Bob')])
[False  True  True False  True  True  True]
[[-0.63128177  0.08622805  2.37703884 -0.74811189]
 [ 1.12524682 -0.85953321  1.49936793 -0.44227359]
 [-1.44121109  0.60309252 -0.5896922   1.177443  ]
 [ 0.25404221  0.67925263 -1.95840484 -1.23057716]
 [ 2.27354722 -0.0742969   0.44599971  1.60997101]]

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

cond = names == 'Bob'
print(data[~cond])
[[-0.63128177  0.08622805  2.37703884 -0.74811189]
 [ 1.12524682 -0.85953321  1.49936793 -0.44227359]
 [-1.44121109  0.60309252 -0.5896922   1.177443  ]
 [ 0.25404221  0.67925263 -1.95840484 -1.23057716]
 [ 2.27354722 -0.0742969   0.44599971  1.60997101]]

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

mask = (names == 'Bob') | (names == 'Will')
print(mask)
print(data[mask])
[ True False  True  True  True False False]
[[ 0.78960872  0.07797085 -1.66217385  0.71805312]
 [ 1.12524682 -0.85953321  1.49936793 -0.44227359]
 [ 0.37364903 -1.93452554 -1.15493364  1.36474335]
 [-1.44121109  0.60309252 -0.5896922   1.177443  ]]

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

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

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

data[data < 0] = 0
print (data)
[[ 0.78960872  0.07797085  0.          0.71805312]
 [ 0.          0.08622805  2.37703884  0.        ]
 [ 1.12524682  0.          1.49936793  0.        ]
 [ 0.37364903  0.          0.          1.36474335]
 [ 0.          0.60309252  0.          1.177443  ]
 [ 0.25404221  0.67925263  0.          0.        ]
 [ 2.27354722  0.          0.44599971  1.60997101]]
data[names != 'Joe'] = 7
print(data)
[[ 7.          7.          7.          7.        ]
 [ 0.          0.08622805  2.37703884  0.        ]
 [ 7.          7.          7.          7.        ]
 [ 7.          7.          7.          7.        ]
 [ 7.          7.          7.          7.        ]
 [ 0.25404221  0.67925263  0.          0.        ]
 [ 2.27354722  0.          0.44599971  1.60997101]]

1.1.8 花式索引

花式索引(Fancy indexing)是一个NumPy术语,它指的是利用整数数组进行索引。

arr = np.empty((8, 4))
for i in range(8):
  arr[i] = i
print (arr)
[[ 0.  0.  0.  0.]
 [ 1.  1.  1.  1.]
 [ 2.  2.  2.  2.]
 [ 3.  3.  3.  3.]
 [ 4.  4.  4.  4.]
 [ 5.  5.  5.  5.]
 [ 6.  6.  6.  6.]
 [ 7.  7.  7.  7.]]

为了以特定顺序选取行子集,只需传入一个用于指定顺序的整数列表或ndarray即可:

print (arr[[4, 3, 0, 6]])
[[ 4.  4.  4.  4.]
 [ 3.  3.  3.  3.]
 [ 0.  0.  0.  0.]
 [ 6.  6.  6.  6.]]
print(arr[[-3, -5, -7]])
[[ 5.  5.  5.  5.]
 [ 3.  3.  3.  3.]
 [ 1.  1.  1.  1.]]

一次传入多个索引数组会有一点特别。它返回的是一个一维数组,其中的元素对应各个索引元组:

arr = np.arange(32).reshape((8, 4))
print(arr)
print(arr[[1, 5, 7, 2], [0, 3, 1, 2]])
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]
 [24 25 26 27]
 [28 29 30 31]]
[ 4 23 29 10]

最终选出的是元素(1,0)、(5,3)、(7,1)和(2,2)。无论数组是多少维的,花式索引总是一维的。

这个花式索引的行为可能会跟某些用户的预期不一样(包括我在内),选取矩阵的行列子集应该是矩形区域的形式才对。下面是得到该结果的一个办法:

print(arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]])
[[ 4  7  5  6]
 [20 23 21 22]
 [28 31 29 30]
 [ 8 11  9 10]]

记住,花式索引跟切片不一样,它总是将数据复制到新数组中。

1.1.9数组转置与轴对换

转置是重塑的一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作)。数组不仅有transpose方法,还有一个特殊的T属性,在进行矩阵计算时,经常需要用到该操作,比如利用np.dot计算矩阵内积:

arr = np.arange(15).reshape((3, 5))
print(arr)
print(arr.T)
print(np.dot(arr,arr.T))

[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
[[ 0  5 10]
 [ 1  6 11]
 [ 2  7 12]
 [ 3  8 13]
 [ 4  9 14]]
[[ 30  80 130]
 [ 80 255 430]
 [130 430 730]]

对于高维数组,transpose需要得到一个由轴编号组成的元组才能对这些轴进行转置(比较费脑子):

arr = np.arange(16).reshape((2, 2, 4))
print(arr)
print('==========分割线==============')
print(arr.transpose((1, 0, 2)))
[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]]
==========分割线==============
[[[ 0  1  2  3]
  [ 8  9 10 11]]

 [[ 4  5  6  7]
  [12 13 14 15]]]

这里,第一个轴被换成了第二个,第二个轴被换成了第一个,最后一个轴不变。

简单的转置可以使用.T,它其实就是进行轴对换而已。ndarray还有一个swapaxes方法,它需要接受一对轴编号:

print(arr)
print('==========分割线==============')
print(arr.swapaxes(1, 2))
[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]]
==========分割线==============
[[[ 0  4]
  [ 1  5]
  [ 2  6]
  [ 3  7]]

 [[ 8 12]
  [ 9 13]
  [10 14]
  [11 15]]]

swapaxes也是返回源数据的视图(不会进行任何复制操作)。

1.2通用函数:快速的元素级数组函数

通用函数(即ufunc)是一种对ndarray中的数据执行元素级运算的函数。你可以将其看做简单函数(接受一个或多个标量值,并产生一个或多个标量值)的矢量化包装器。许多ufunc都是简单的元素级变体,如sqrt和exp:

arr = np.arange(10)
print(arr)
print(np.sqrt(arr))
print(np.exp(arr))
[0 1 2 3 4 5 6 7 8 9]
[ 0.          1.          1.41421356  1.73205081  2.          2.23606798
  2.44948974  2.64575131  2.82842712  3.        ]
[  1.00000000e+00   2.71828183e+00   7.38905610e+00   2.00855369e+01
   5.45981500e+01   1.48413159e+02   4.03428793e+02   1.09663316e+03
   2.98095799e+03   8.10308393e+03]

这些都是一元(unary)ufunc。另外一些(如add或maximum)接受2个数组(因此也叫二元(binary)ufunc),并返回一个结果数组:

x = np.random.randn(8)
y = np.random.randn(8)
print(x)
print(y)
print(np.maximum(x, y))
[-0.89975721 -0.12529661  1.30973587  0.35581081  0.77526615 -0.6876156
  1.26948427 -1.76006942]
[-0.16082986 -1.68955537  0.94858417 -0.52966028 -1.95181588 -0.30713809
 -0.61134498 -1.08940339]
[-0.16082986 -0.12529661  1.30973587  0.35581081  0.77526615 -0.30713809
  1.26948427 -1.08940339]

虽然并不常见,但有些ufunc的确可以返回多个数组。modf就是一个例子,它是Python内置函数divmod的矢量化版本,它会返回浮点数数组的小数和整数部分:

arr = np.random.randn(7) * 5
print(arr)
remainder, whole_part = np.modf(arr)
print(remainder)
print(whole_part)
[ -2.88452855  -1.14582772   3.00420715   1.22281642  -0.38185437
 -11.36241841   6.52291062]
[-0.88452855 -0.14582772  0.00420715  0.22281642 -0.38185437 -0.36241841
  0.52291062]
[ -2.  -1.   3.   1.  -0. -11.   6.]
print(arr)
print(np.sqrt(arr))
print(np.sqrt(arr, arr))
print(arr)
[ -2.88452855  -1.14582772   3.00420715   1.22281642  -0.38185437
 -11.36241841   6.52291062]
[        nan         nan  1.73326488  1.1058103          nan         nan
  2.55399895]
[        nan         nan  1.73326488  1.1058103          nan         nan
  2.55399895]
[        nan         nan  1.73326488  1.1058103          nan         nan
  2.55399895]

1.3利用数组进行数据处理

作为简单的例子,假设我们想要在一组值(网格型)上计算函数 $\sqrt{x^2+y^2}$。np.meshgrid函数接受两个一维数组,并产生两个二维矩阵(对应于两个数组中所有的(x,y)对):

points = np.arange(-5, 5, 0.01) # 1000 equally spaced points
xs, ys = np.meshgrid(points, points)
print(ys)
print(xs)
[[-5.   -5.   -5.   ..., -5.   -5.   -5.  ]
 [-4.99 -4.99 -4.99 ..., -4.99 -4.99 -4.99]
 [-4.98 -4.98 -4.98 ..., -4.98 -4.98 -4.98]
 ..., 
 [ 4.97  4.97  4.97 ...,  4.97  4.97  4.97]
 [ 4.98  4.98  4.98 ...,  4.98  4.98  4.98]
 [ 4.99  4.99  4.99 ...,  4.99  4.99  4.99]]
[[-5.   -4.99 -4.98 ...,  4.97  4.98  4.99]
 [-5.   -4.99 -4.98 ...,  4.97  4.98  4.99]
 [-5.   -4.99 -4.98 ...,  4.97  4.98  4.99]
 ..., 
 [-5.   -4.99 -4.98 ...,  4.97  4.98  4.99]
 [-5.   -4.99 -4.98 ...,  4.97  4.98  4.99]
 [-5.   -4.99 -4.98 ...,  4.97  4.98  4.99]]
z = np.sqrt(xs ** 2 + ys ** 2)
print(z)
[[ 7.07106781  7.06400028  7.05693985 ...,  7.04988652  7.05693985
   7.06400028]
 [ 7.06400028  7.05692568  7.04985815 ...,  7.04279774  7.04985815
   7.05692568]
 [ 7.05693985  7.04985815  7.04278354 ...,  7.03571603  7.04278354
   7.04985815]
 ..., 
 [ 7.04988652  7.04279774  7.03571603 ...,  7.0286414   7.03571603
   7.04279774]
 [ 7.05693985  7.04985815  7.04278354 ...,  7.03571603  7.04278354
   7.04985815]
 [ 7.06400028  7.05692568  7.04985815 ...,  7.04279774  7.04985815
   7.05692568]]

1.3.1将条件逻辑表述为数组运算

numpy.where函数是三元表达式x if condition else y的矢量化版本。假设我们有一个布尔数组和两个值数组:

xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = [(x if c else y)
	for x, y, c in zip(xarr, yarr, cond)]
print(result)
[1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]

这有几个问题。第一,它对大数组的处理速度不是很快(因为所有工作都是由纯Python完成的)。第二,无法用于多维数组。若使用np.where,则可以将该功能写得非常简洁:

result = np.where(cond, xarr, yarr)
print(result)
[ 1.1  2.2  1.3  1.4  2.5]

np.where的第二个和第三个参数不必是数组,它们都可以是标量值。在数据分析工作中,where通常用于根据另一个数组而产生一个新的数组。假设有一个由随机数据组成的矩阵,你希望将所有正值替换为2,将所有负值替换为-2。若利用np.where,则会非常简单:

arr = np.random.randn(4, 4)
print(arr)
print(arr > 0)
print(np.where(arr > 0, 2, -2))
[[ 0.43108163 -1.62297411 -0.35272749 -0.11121756]
 [ 1.09516004 -1.09607697 -1.18267922  0.41269814]
 [ 0.792395   -0.15106096 -1.16765629 -0.87732462]
 [ 0.36735315  0.03524087 -1.38967914  1.09297679]]
[[ True False False False]
 [ True False False  True]
 [ True False False False]
 [ True  True False  True]]
[[ 2 -2 -2 -2]
 [ 2 -2 -2  2]
 [ 2 -2 -2 -2]
 [ 2  2 -2  2]]

使用np.where,可以将标量和数组结合起来。例如,我可用常数2替换arr中所有正的值:

print(np.where(arr > 0, 2, arr))
[[ 2.         -1.62297411 -0.35272749 -0.11121756]
 [ 2.         -1.09607697 -1.18267922  2.        ]
 [ 2.         -0.15106096 -1.16765629 -0.87732462]
 [ 2.          2.         -1.38967914  2.        ]]

传递给where的数组大小可以不相等,甚至可以是标量值。

1.3.2数学和统计方法

可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算。sum、mean以及标准差std等聚合计算(aggregation,通常叫做约简(reduction))既可以当做数组的实例方法调用,也可以当做顶级NumPy函数使用。

这里,我生成了一些正态分布随机数据,然后做了聚类统计:

[[-0.22207059  0.08128119 -0.5873026  -1.16505974]
 [ 0.89885335  2.02110103  1.25763195  0.62924271]
 [ 0.7146921   0.66485384 -1.01937409  0.88249022]
 [ 0.84734176 -0.23980799 -1.103781    1.26793628]
 [ 1.12247414 -0.09624304 -0.1854838   1.67371653]]
0.372124612687
0.372124612687
7.44249225373

mean和sum这类的函数可以接受一个axis选项参数,用于计算该轴向上的统计值,最终结果是一个少一维的数组:

print(arr.mean(axis=1))
print(arr.sum(axis=0))
[-0.47328793  1.20170726  0.31066552  0.19292226  0.62861596]
[ 3.36129076  2.43118502 -1.63830954  3.28832601]

这里,arr.mean(1)是“计算行的平均值”,arr.sum(0)是“计算每列的和”。

其他如cumsum和cumprod之类的方法则不聚合,而是产生一个由中间结果组成的数组:

arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
print(arr.cumsum())
[ 0  1  3  6 10 15 21 28]
在多维数组中,累加函数(如cumsum)返回的是同样大小的数组,但是会根据每个低维的切片沿着标记轴计算部分聚类:
arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
print(arr)
print(arr.cumsum(axis=0))
print(arr.cumprod(axis=1))
[[0 1 2]
 [3 4 5]
 [6 7 8]]
[[ 0  1  2]
 [ 3  5  7]
 [ 9 12 15]]
[[  0   0   0]
 [  3  12  60]
 [  6  42 336]]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值