您的位置:首页 > 编程语言 > Python开发

numpy基础——ndarray对象方法

2016-10-31 15:35 246 查看
上一篇主要介绍了ndarray对象的一些基本属性以及创建ndarray对象的一些非常常用的方法。接下来主要介绍ndarray对象比较常用的对象方法。需要注意的是,以下ndarray对象方法也是numpy中的函数:
all, any, argmax, argmin, argpartition, argsort, choose, clip, compress, copy, cumprod, cumsum, diagonal, imag, max, mean, min, nonzero, partition, prod, ptp, put, ravel, real, repeat, reshape, round, searchsorted, sort, squeeze, std, sum, swapaxes, take, trace, transpose, var


1 数组转换方法

常用方法功能
ndarray.item(*args)复制数组中的一个元素,并返回
ndarray.tolist()将数组转换成python标准list
ndarray.itemset(*args)修改数组中某个元素的值
ndarray.tostring([order])构建一个包含ndarray的原始字节数据的字节字符串
ndarray.tobytes([order])功能同tostring
ndarray.byteswap(inplace)将ndarray中每个元素中的字节进行大小端转换
ndarray.copy([order])复制数组并返回(深拷贝)
ndarray.fill(value)使用值value填充数组
示例:

>>> a = np.random.randint(12, size=(3,4))
>>> a
array([[11,  1,  0, 11],
[11,  0,  4,  6],
[ 0,  1,  6,  7]])
>>> a.item(7)      #获取第7个元素
6
>>> a.item((1, 2))    #获取元组对应的元素
4
>>> a.itemset(7, 111)    #设置元素
>>> a
array([[ 11,   1,   0,  11],
[ 11,   0,   4, 111],
[  0,   1,   6,   7]])
>>> a.itemset((1, 2), 12)
>>> a
array([[ 11,   1,   0,  11],
[ 11,   0,  12, 111],
[  0,   1,   6,   7]])
>>> a.tolist()      #返回python标准列表,
[[11, 1, 0, 11], [11, 0, 4, 6], [0, 1, 6, 7]]
>>> a.tostring()
'\x0b\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00'
>>> b = a.copy()      #深拷贝,b与a是两个无关的数组
>>> b[0,0] = 10
>>> b
array([[10,  1,  0, 11],
[11,  0,  4,  6],
[ 0,  1,  6,  7]])
>>> a
array([[11,  1,  0, 11],
[11,  0,  4,  6],
[ 0,  1,  6,  7]])
>>> b.fill(9)
>>> b
array([[9, 9, 9, 9],
[9, 9, 9, 9],
[9, 9, 9, 9]])
>>> a.byteswap()      #元素大小端转换,a不变
array([[ 792633534417207296,   72057594037927936,                   0,
792633534417207296],
[ 792633534417207296,                   0,  864691128455135232,
7998392938210000896],
[                  0,   72057594037927936,  432345564227567616,
504403158265495552]])
>>> a
array([[ 11,   1,   0,  11],
[ 11,   0,  12, 111],
[  0,   1,   6,   7]])
>>> a.byteswap(True)    #原地转换,a被修改
array([[ 792633534417207296,   72057594037927936,                   0,
792633534417207296],
[ 792633534417207296,                   0,  864691128455135232,
7998392938210000896],
[                  0,   72057594037927936,  432345564227567616,
504403158265495552]])
>>> a
array([[ 792633534417207296,   72057594037927936,                   0,
792633534417207296],
[ 792633534417207296,                   0,  864691128455135232,
7998392938210000896],
[                  0,   72057594037927936,  432345564227567616,
504403158265495552]])


如下几个方法:
ndarray.tofile, ndarray.dump, ndarray.dumps, ndarray.astype, ndarray.view, ndarray.getfield, ndarray.setflags
,还没有用过,暂时不对其进行详细介绍,等用到了在补充。关于这些方法的详细介绍可以查阅numpy的官方文档。

2 形状操作

常用方法功能
ndarray.reshape(shape[,order])返回一个具有相同数据域,但shape不一样的视图
ndarray.resize(new_shape[,orefcheck])原地修改数组的形状(需要保持元素个数前后相同)
ndarray.transpose(*axes)返回数组针对某一轴进行转置的视图
ndarray.swapaxes(axis1, asix2)返回数组axis1轴与axis2轴互换的视图
ndarray.flatten([order])返回将原数组压缩成一维数组的拷贝(全新的数组)
ndarray.ravel([order])返回将原数组压缩成一维数组的视图
ndarray.squeeze([axis])返回将原数组中的shape中axis==1的轴移除之后的视图
注意事项!!!

上述方法中,除
resize
flatten
外其他的方法返回的都是原数组修改shape或者axes之后的视图,也就是说,对返回数组中的元素进行修改,原数组中对应的元素也会被修改(因为它们是公用同一个数据域的)。同时,
resize
方法会修改原数组的shape属性,其他方法不会修改原数组任何内部数据。

示例:

>>> x = np.arange(0,12)
>>> x
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> x_reshape = x.reshape((3,4))
>>> x_reshape
array([[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]])
>>> x_reshape[0,0] = 10    #修改返回数组的元素,直接影响原数组中的元素值(数据域是相同的)
>>> x
array([10,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> x[0,0] = 0

>>> x.resize((3,4))    #resize没有返回值,会直接修改数组的shape,如下所示
>>> x
array([[10,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]])

>>> x_transpose = x.transpose()  #对于二维数组,返回数组的转置
>>> x_transpose
array([[ 0,  4,  8],
[ 1,  5,  9],
[ 2,  6, 10],
[ 3,  7, 11]])
>>> x.resize(2,2,3)
>>> x
array([[[ 0,  1,  2],
[ 3,  4,  5]],

[[ 6,  7,  8],
[ 9, 10, 11]]])

>>> x.swapaxes(0,2)  #本质上还是修改strides以及shape
array([[[ 0,  6],
[ 3,  9]],
[[ 1,  7],
[ 4, 10]],
[[ 2,  8],
[ 5, 11]]])
>>> x.swapaxes(0,2).strides  #互换strides中第0、2位置上的数值
(8, 24, 48)
>>> x.strides
(48, 24, 8)

>>> x
array([[[ 0,  1,  2],
[ 3,  4,  5]],
[[ 6,  7,  8],
[ 9, 10, 11]]])
>>> y = x.flatten()  #返回一个全新的数组
>>> y
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> y[0] = 100
>>> y
array([100,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11])
>>> x  #修改y中元素的值,不影响x中的元素
array([[[ 0,  1,  2],
[ 3,  4,  5]],
[[ 6,  7,  8],
[ 9, 10, 11]]])

>>> x_ravel = x.ravel()  #与flatten类似,但是返回的是原数组的视图,数据域是相同的
>>> x_ravel
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

>>> x.resize((1,2,2,3,1))
>>> x
array([[[[[ 0],
[ 1],
[ 2]],
[[ 3],
[ 4],
[ 5]]],
[[[ 6],
[ 7],
[ 8]],
[[ 9],
[10],
[11]]]]])
>>> x.squeeze()  #移除shape中值为1的项
array([[[ 0,  1,  2],
[ 3,  4,  5]],
[[ 6,  7,  8],
[ 9, 10, 11]]])
>>> x.shape
(1, 2, 2, 3, 1)
>>> x.squeeze().shape
(2, 2, 3)


tips: transpose

1.
transpose
的本质是按照参数
axes
修改了
strides
以及
shape
属性(自己的理解):

1)提供axes,按照axes中提供的各个轴的新位置调整
strides
属性中对应位置上的值

2)不提供axes,取原
strides
的对称形式作为返回数组的
strides
属性

3)
shape
属性也是按照上述方式修改

示例:

>>> x  #先看二维的情形
array([[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]])
>>> x.transpose()  #不提供axes,等同于x.transpose((1, 0))
array([[ 0,  4,  8],
[ 1,  5,  9],
[ 2,  6, 10],
[ 3,  7, 11]])
>>> x.strides
(32, 8)
>>> x.transpose().strides
(8, 32)
>>> x.transpose((0,1))  #提供axes,各个轴的位置没有变化,结果与x是一样的
array([[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]])
>>> x.transpose((0,1)).strides  #strides参数也没有变化
(32, 8)
>>> y  #再看三维的情形
array([[[ 0,  1,  2],
[ 3,  4,  5]],
[[ 6,  7,  8],
[ 9, 10, 11]]])
>>> y.transpose()  #不带axes参数,等同于y.transpose((2,1,0))
array([[[ 0,  6],
[ 3,  9]],
[[ 1,  7],
[ 4, 10]],
[[ 2,  8],
[ 5, 11]]])
>>> y.transpose().strides
(8, 24, 48)
>>> y.strides
(48, 24, 8)
>>> y.transpose((2,0,1))  #带axes参数
array([[[ 0,  3],
[ 6,  9]],
[[ 1,  4],
[ 7, 10]],
[[ 2,  5],
[ 8, 11]]])
>>> y.transpose((2,0,1)).strides  #注意strides各个参数的位置与原来strides参数的位置,正好是转置时axes的对应位置
(8, 48, 24)


不提供axes参数时,转换前后shape、strides以及数据有如下关系:

1)转置前
a.shape=(i[0], i[1], ..., i[n-2], i[n-1])
,转置后的:
a.transpose().shape=(i[n-1], i[n-2], ..., i[1], i[0])


2)转置前
`a.strides=(j[0], j[1], ..., j[n-2], j[n-1])
,转置后:
a.transpose().strides=(j[n-1], j[n-2], ..., j[1], j[0])


3)数据:
a[i[0], i[1], ..., i[n-2], i[n-1]] == a.transpose()[i[n-1], i[n-2], ..., i[1], i[0]]


思考提供axes参数时,上述关系是怎样的?

3 计算

关于ndarray对象的很多计算方法都有一个
axis
参数,它有如下作用:

1. 当
axis=None
(默认)时,数组被当成一个一维数组,对数组的计算操作是对整个数组进行的,比如
sum
方法,就是求数组中所有元素的和;

2. 当
axis
被指定为一个int整数时,对数组的计算操作是以提供的
axis
轴进行的。

示例:

>>> a
array([[[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]],

[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>> a.sum(0)  #等价于a[0,:,:] + a[1,:,:]
array([[12, 14, 16, 18],
[20, 22, 24, 26],
[28, 30, 32, 34]])
>>> a.sum(1)  #等价于a[:,0,:] + a[:,1,:] + a[:,2,:]
array([[12, 15, 18, 21],
[48, 51, 54, 57]])
>>> a.sum(2)  #等价于a[:,:,0]+a[:,:,1]+a[:,:,2]+a[:,:,3]
array([[ 6, 22, 38],
[54, 70, 86]])


常用方法功能
ndarray.max([axis, out, keepdims])返回根据指定的axis计算最大值
ndarray.argmax([axis, out])返回根据指定axis计算最大值的索引
ndarray.min([axis, out, keepdims])返回根据指定的axis计算最小值
ndarray.argmin([axis, out])返回根据指定axis计算最小值的索引
ndarray.ptp([axis, out])返回根据指定axis计算最大值与最小值的差
ndarray.clip([min, max, out])返回数组元素限制在[min, max]之间的新数组(小于min的转为min,大于max的转为max)
ndarray.round([decimals, out])返回指定精度的数组(四舍五入)
ndarray.trace([offset, axis1, axis2, dtype, out])返回数组的迹(对角线元素的和)
ndarray.sum([axis, dtype, out, keepdims])根据指定axis计算数组的和,默认求所有元素的和
ndarray.cumsum([axis, dtype, out])根据指定axis计算数组的累积和
ndarray.mean([axis, dtype, out, keepdims])根据指定axis计算数组的平均值
ndarray.var([axis, dtype, out, ddof, keepdims])根据指定的axis计算数组的方差
ndarray.std([axis, dtype, out, ddof, keepdims])根据指定axis计算数组的标准差
ndarray.prod([axis, dtype, out, keepdims])根据指定axis计算数组的积
ndarray.cumprod([axis, dtype, out])根据指定axis计算数据的累计积
ndarray.all([axis, dtype, out])根据指定axis判断所有元素是否全部为真
ndarray.any([axis, out, keepdims])根据指定axis判断是否有元素为真
>>> a
array([[2, 3, 4, 9],
[8, 7, 6, 5],
[4, 3, 5, 8]])
>>> a.max()
9
>>> a.max(axis=0)  #shape=(4,),即原shape去掉第0个axis
array([8, 7, 6, 9])
>>> a.max(axis=1)  #shape=(3,),即原shape去掉第1个axis
array([9, 8, 8])
>>> a.argmax()
3
>>> a.argmax(axis=0)
array([1, 1, 1, 0])
>>> a.argmax(axis=1)
array([3, 0, 3])
>>> b = a.flatten()
>>> b
array([2, 3, 4, 9, 8, 7, 6, 5, 4, 3, 5, 8])
>>> b.clip(3, 5)  #数组元素限定在[3, 5]之间
array([3, 3, 4, 5, 5, 5, 5, 5, 4, 3, 5, 5])
>>> a.resize((2,2,3))
>>> a
array([[[2, 3, 4],
[9, 8, 7]],
[[6, 5, 4],
[3, 5, 8]]])
>>> a.trace(0,axis=0, axis=1)  #等同于[trace(a[:,:,0]), trace(a[:,:,1], trace(a[:,:,2])];shape=(3,),即原shape去掉第0,1个axis
array([ 5,  8, 12])
>>> np.eye(3).trace()  #对角线元素的和
3.0
>>> b.reshape((3,4))
array([[2, 3, 4, 9],
[8, 7, 6, 5],
[4, 3, 5, 8]])
>>> b.reshape((3,4)).std(0)
array([ 2.49443826,  1.88561808,  0.81649658,  1.69967317])
>>> b.reshape((3,4)).std(1)
array([ 2.6925824 ,  1.11803399,  1.87082869])
>>> x = np.arange(8)
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7])
>>> x.cumsum()  #累计和
array([ 0,  1,  3,  6, 10, 15, 21, 28])
>>> x = np.arange(1,9)
>>> x
array([1, 2, 3, 4, 5, 6, 7, 8])
>>> x.cumprod()  #累计积
array([    1,     2,     6,    24,   120,   720,  5040, 40320])


4 选择元素以及操作

常用方法方法功能
ndarray.take(indices[, axis, out, model])从原数组中根据指定的索引获取对应元素,并构成一个新的数组返回
ndarray.put(indices, values[, mode])将数组中indices指定的位置设置为values中对应的元素值
ndarray.repeat(repeats[, axis])根据指定的axis重复数组中的元素
ndarray.sort([axis, kind, order])原地对数组元素进行排序
ndarray.argsort([axis, kind, order])返回对数组进行升序排序之后的索引
ndarray.partition(kth[, axis, kind, order])将数组重新排列,所有小于kth的值在kth的左侧,所有大于或等于kth的值在kth的右侧
ndarray.argpartition(kth[, axis, kind, order])对数组执行partition之后的元素索引
ndarray.searchsorted(v[, side, sorter])若将v插入到当前有序的数组中,返回插入的位置索引
ndarray.nonzero()返回数组中非零元素的索引
ndarray.diagonal([offset, axis1, axis2])返回指定的对角线
>>> a
array([2, 3, 4, 9, 8, 7, 6, 5, 4, 3, 5, 8])
>>> a.take([0,3,6])
array([2, 9, 6])
>>> a.take([[2, 5], [3,6]])  #返回数组的形状与indices形状相同
array([[4, 7],
[9, 6]])
>>> a.put([0, -1], [0, 111])
>>> a
array([  0,   3,   4,   9,   8,   7,   6,   5,   4,   3,   5, 111])

>>> a.sort()  #原地排序
>>> a
array([  0,   3,   3,   4,   4,   5,   5,   6,   7,   8,   9, 111])

>>> b
array([  0,   3,   4,   9,   8,   7,   6,   5,   4,   3,   5, 111])
>>> b_idx = b.argsort()  #获取排序索引
>>> b_idx
array([ 0,  1,  9,  2,  8,  7, 10,  6,  5,  4,  3, 11])
>>> b[b_idx]  #根据排序索引获取b中元素,正好是排序好的
array([  0,   3,   3,   4,   4,   5,   5,   6,   7,   8,   9, 111])

>>> c
array([  0,   3,   4,   9,   8,   7,   6,   5,   4,   3,   5, 111])
>>> c.partition(5)
>>> c
array([  3,   4,   4,   0,   3,   5,   6,   5,   7,   8,   9, 111])

>>> a
array([  0,   3,   3,   4,   4,   5,   5,   6,   7,   8,   9, 111])
>>> a.searchsorted(2)
1
>>> a.searchsorted(10)
11
>>> a.searchsorted(3)  #side默认为lift
1
>>> a.searchsorted(3, side="right")
3

>>> e = np.eye(4)
>>> e
array([[ 1.,  0.,  0.,  0.],
[ 0.,  1.,  0.,  0.],
[ 0.,  0.,  1.,  0.],
[ 0.,  0.,  0.,  1.]])
>>> e.nonzero()
(array([0, 1, 2, 3]), array([0, 1, 2, 3]))
>>> e[e.nonzero()]
array([ 1.,  1.,  1.,  1.])

>>> a = np.arange(4).reshape(2,2)
>>> a
array([[0, 1],
[2, 3]])
>>> a.diagonal()  #二维数组取对角线元素
array([0, 3])
>>> a = np.arange(8).reshape(2,2,2)
>>> a
array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])
>>> a.diagonal(offset=0, axis1=0, axis2=1)  #三维数组根据指定axis取对角线,本质是取下面两个二维数组的对角线
array([[0, 6],
[1, 7]])
>>> a[:,:,0]    #对角线[0, 6]
array([[0, 2],
[4, 6]])
>>> a[:,:,1]    #对角线[1, 7]
array([[1, 3],
[5, 7]])
>>> a.diagonal(offset=0, axis1=0, axis2=2)
array([[0, 5],
[2, 7]])
>>> a[:,0,:]
array([[0, 1],
[4, 5]])
>>> a[:,1,:]
array([[2, 3],
[6, 7]])
>>> a.diagonal(offset=0, axis1=1, axis2=2)
array([[0, 3],
[4, 7]])
>>> a[0,:,:]
array([[0, 1],
[2, 3]])
>>> a[1,:,:]
array([[4, 5],
[6, 7]])
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  numpy