NumPy之:ndarray多维数组操作

简介: NumPy之:ndarray多维数组操作

NumPy之:ndarray多维数组操作


目录



简介


NumPy一个非常重要的作用就是可以进行多维数组的操作,多维数组对象也叫做ndarray。我们可以在ndarray的基础上进行一系列复杂的数学运算。


本文将会介绍一些基本常见的ndarray操作,大家可以在数据分析中使用。


创建ndarray


创建ndarray有很多种方法,我们可以使用np.random来随机生成数据:


import numpy as np
# Generate some random data
data = np.random.randn(2, 3)
data


array([[ 0.0929,  0.2817,  0.769 ],
       [ 1.2464,  1.0072, -1.2962]])


除了随机创建之外,还可以从list中创建:


data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)


array([6. , 7.5, 8. , 0. , 1. ])


从list中创建多维数组:


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


array([[1, 2, 3, 4],
       [5, 6, 7, 8]])


使用np.zeros创建初始值为0的数组:


np.zeros(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])


创建2维数组:


np.zeros((3, 6))


array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]])


使用empty创建3维数组:


np.empty((2, 3, 2))


array([[[0., 0.],
        [0., 0.],
        [0., 0.]],
       [[0., 0.],
        [0., 0.],
        [0., 0.]]])


注意,这里我们看到empty创建的数组值为0,其实并不是一定的,empty会从内存中随机挑选空间来返回,并不能保证这些空间中没有值。所以我们在使用empty创建数组之后,在使用之前,还要记得初始化他们。


使用arange创建范围类的数组:


np.arange(15)


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


指定数组中元素的dtype:


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


ndarray的属性


可以通过data.shape获得数组的形状。


data.shape
(2, 3)


通过ndim获取维数信息:


arr2.ndim
2


可以通过data.dtype获得具体的数据类型。


data.dtype
dtype('float64')


ndarray中元素的类型转换


在创建好一个类型的ndarray之后,还可以对其进行转换:


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


上面我们使用astype将int64类型的ndarray转换成了float64类型的。


如果转换类型的范围不匹配,则会自动进行截断操作:


arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
arr.astype(np.int32)
array([ 3, -1, -2,  0, 12, 10], dtype=int32)


注意,这里是把小数截断,并没有向上或者向下取整。


ndarray的数学运算


数组可以和常量进行运算,也可以和数组进行运算:


arr = np.array([[1., 2., 3.], [4., 5., 6.]])
arr * arr
array([[ 1.,  4.,  9.],
       [16., 25., 36.]])
arr + 10
array([[11., 12., 13.],
       [14., 15., 16.]])
arr - arr
array([[0., 0., 0.],
       [0., 0., 0.]])
1 / arr
array([[1.    , 0.5   , 0.3333],
       [0.25  , 0.2   , 0.1667]])
arr ** 0.5
array([[1.    , 1.4142, 1.7321],
       [2.    , 2.2361, 2.4495]])


数组之间还可以进行比较,比较的是数组中每个元素的大小:


arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
arr2 > arr
array([[False,  True, False],
       [ True, False,  True]])


index和切片


基本使用


先看下index和切片的基本使用,index基本上和普通数组的使用方式是一样的,用来访问数组中某一个元素。


切片要注意的是切片后返回的数组中的元素是原数组中元素的引用,修改切片的数组会影响到原数组。


# 构建一维数组
arr = np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# index访问
arr[5]
5
# 切片访问
arr[5:8]
array([5, 6, 7])
# 切片修改
arr[5:8] = 12
array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])
# 切片可以修改原数组的值
arr_slice = arr[5:8]
arr_slice[1] = 12345
arr
array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,
           9])
# 构建二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2]
array([7, 8, 9])
# index 二维数组
arr2d[0][2]
3
# index二维数组
arr2d[0, 2]
3
# 构建三维数组
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
arr3d
array([[[ 1,  2,  3],
        [ 4,  5,  6]],
       [[ 7,  8,  9],
        [10, 11, 12]]])
# index三维数组
arr3d[0]
array([[1, 2, 3],
       [4, 5, 6]])
# copy是硬拷贝,和原数组的值相互不影响
old_values = arr3d[0].copy()
arr3d[0] = 42
arr3d
array([[[42, 42, 42],
        [42, 42, 42]],
       [[ 7,  8,  9],
        [10, 11, 12]]])
arr3d[0] = old_values
arr3d
array([[[ 1,  2,  3],
        [ 4,  5,  6]],
       [[ 7,  8,  9],
        [10, 11, 12]]])
# index 三维数组
arr3d[1, 0]
array([7, 8, 9])
x = arr3d[1]
x
array([[ 7,  8,  9],
       [10, 11, 12]])
x[0]
array([7, 8, 9])


index with slice


slice还可以作为index使用,作为index使用表示的就是一个index范围值。


作为index表示的slice可以有多种形式。


有头有尾的,表示index从1开始到6-1结束:


arr[1:6]


array([ 1,  2,  3,  4, 64])


无头有尾的,表示index从0开始,到尾-1结束:


arr2d[:2]


array([[1, 2, 3],
       [4, 5, 6]])


有头无尾的,表示从头开始,到所有的数据结束:


arr2d[:2, 1:]


array([[2, 3],
       [5, 6]])


arr2d[1, :2]


array([4, 5])


boolean index


index还可以使用boolean值,表示是否选择这一个index的数据。


我们先看下怎么构建一个boolean类型的数组:


names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
names == 'Bob'
array([ True, False, False,  True, False, False, False])


上面我们通过比较的方式返回了一个只包含True和False的数组。


这个数组可以作为index值来访问数组:


#  构建一个7 * 4 的数组
data = np.random.randn(7, 4)
array([[ 0.275 ,  0.2289,  1.3529,  0.8864],
       [-2.0016, -0.3718,  1.669 , -0.4386],
       [-0.5397,  0.477 ,  3.2489, -1.0212],
       [-0.5771,  0.1241,  0.3026,  0.5238],
       [ 0.0009,  1.3438, -0.7135, -0.8312],
       [-2.3702, -1.8608, -0.8608,  0.5601],
       [-1.2659,  0.1198, -1.0635,  0.3329]])
# 通过boolean数组来访问:
data[names == 'Bob']
array([[ 0.275 ,  0.2289,  1.3529,  0.8864],
       [-0.5771,  0.1241,  0.3026,  0.5238]])


在索引行的时候,还可以索引列:


data[names == 'Bob', 3]
array([0.8864, 0.5238])


可以用 ~符号来取反:


data[~(names == 'Bob')]
array([[-2.0016, -0.3718,  1.669 , -0.4386],
       [-0.5397,  0.477 ,  3.2489, -1.0212],
       [ 0.0009,  1.3438, -0.7135, -0.8312],
       [-2.3702, -1.8608, -0.8608,  0.5601],
       [-1.2659,  0.1198, -1.0635,  0.3329]])


我们可以通过布尔型数组设置值,在实际的项目中非常有用:


data[data < 0] = 0
array([[0.275 , 0.2289, 1.3529, 0.8864],
       [0.    , 0.    , 1.669 , 0.    ],
       [0.    , 0.477 , 3.2489, 0.    ],
       [0.    , 0.1241, 0.3026, 0.5238],
       [0.0009, 1.3438, 0.    , 0.    ],
       [0.    , 0.    , 0.    , 0.5601],
       [0.    , 0.1198, 0.    , 0.3329]])


data[names != 'Joe'] = 7
array([[7.    , 7.    , 7.    , 7.    ],
       [0.    , 0.    , 1.669 , 0.    ],
       [7.    , 7.    , 7.    , 7.    ],
       [7.    , 7.    , 7.    , 7.    ],
       [7.    , 7.    , 7.    , 7.    ],
       [0.    , 0.    , 0.    , 0.5601],
       [0.    , 0.1198, 0.    , 0.3329]])


Fancy indexing


Fancy indexing也叫做花式索引,它是指使用一个整数数组来进行索引。


举个例子,我们先创建一个 8 * 4的数组:


arr = np.empty((8, 4))
for i in range(8):
    arr[i] = i
arr


array([[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.]])


然后使用一个整数数组来索引,那么将会以指定的顺序来选择行:


arr[[4, 3, 0, 6]]
array([[4., 4., 4., 4.],
       [3., 3., 3., 3.],
       [0., 0., 0., 0.],
       [6., 6., 6., 6.]])


还可以使用负值来索引:


arr[[-3, -5, -7]]


array([[5., 5., 5., 5.],
       [3., 3., 3., 3.],
       [1., 1., 1., 1.]])


花式索引还可以组合来使用:


arr = np.arange(32).reshape((8, 4))
arr


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],
       [24, 25, 26, 27],
       [28, 29, 30, 31]])


上面我们构建了一个8 * 4的数组。


arr[[1, 5, 7, 2], [0, 3, 1, 2]]


array([ 4, 23, 29, 10])


然后取他们的第2列的第一个值,第6列的第三个值等等。最后得到一个1维的数组。


数组变换


我们可以在不同维度的数组之间进行变换,还可以转换数组的轴。


reshape方法可以将数组转换成为任意的形状:


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


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


数组还提供了一个T命令,可以将数组的轴进行对调:


arr.T


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


对于高维数组,可以使用transpose来进行轴的转置:


arr = np.arange(16).reshape((2, 2, 4))
arr
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],
       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])
arr.transpose((1, 0, 2))


array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],
       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])


上面的transpose((1, 0, 2)) 怎么理解呢?


其含义是将x,y轴对调,z轴保持不变。


上面我们通过使用reshape((2, 2, 4))方法创建了一个3维,也就是3个轴的数组。 其shape是 2 * 2 * 4 。


先看下对应关系:


(0,0)-》 [ 0, 1, 2, 3]

(0,1)-》 [ 4, 5, 6, 7]

(1,0)-》 [ 8, 9, 10, 11]

(1,1)-》 [12, 13, 14, 15]


转换之后:


(0,0)-》 [ 0, 1, 2, 3]

(0,1)-》 [ 8, 9, 10, 11]

(1,0)-》[ 4, 5, 6, 7]

(1,1)-》 [12, 13, 14, 15]


于是得到了我们上面的的结果。


多维数组的轴转换可能比较复杂,大家多多理解。


还可以使用 swapaxes 来交换两个轴,上面的例子可以重写为:


arr.swapaxes(0,1)
相关文章
|
6月前
|
存储 索引 Python
NumPy 教程 之 NumPy Ndarray 对象 6
**NumPy的ndarray对象是核心特征,是同类型元素的多维数组。它包括数据指针、数据类型(dtype)、形状元组和跨度元组。创建数组使用`numpy.array()`,可通过`dtype`指定数据类型。例如:`a = np.array([1, 2, 3], dtype=complex)`生成复数数组。内存布局遵循C或F顺序。**
29 0
|
5月前
|
机器学习/深度学习 数据采集 并行计算
《零基础实践深度学习》1.7 附录:NumPy介绍 ndarray
这篇文章详细介绍了NumPy库的基本功能和应用,包括ndarray数组的使用、创建、属性查看、数据类型和形状的改变、基本运算、索引和切片,以及统计方法和随机数生成,是进行科学计算和数据分析的基础。
|
6月前
|
存储 索引 Python
NumPy 教程 之 NumPy Ndarray 对象 2
**NumPy的ndarray对象是多维数据的核心,它存储同类型元素,具有形状和 strides。形状描述数组维度大小,strides指示元素间字节偏移。通过`numpy.array()`创建,可指定数据类型、复制选项等。例如,`numpy.array(list, dtype, copy=True, order=&#39;C&#39;, subok=False, ndmin=0)`。**
40 4
|
6月前
|
存储 索引 Python
NumPy 教程 之 NumPy Ndarray 对象 3
**NumPy的ndarray对象是多维数组,存储相同类型数据,用0开始的索引访问。包括数据指针、dtype、形状和跨度元组。创建数组用`np.array()`,参数控制数据类型、复制、排列和维度。例如:`a = np.array([1,2,3])`。输出:`[1 2 3]`。**
41 1
|
6月前
|
数据采集 机器学习/深度学习 数据可视化
了解数据科学面试中的Python数据分析重点,包括Pandas(DataFrame)、NumPy(ndarray)和Matplotlib(图表绘制)。
【7月更文挑战第5天】了解数据科学面试中的Python数据分析重点,包括Pandas(DataFrame)、NumPy(ndarray)和Matplotlib(图表绘制)。数据预处理涉及缺失值(dropna(), fillna())和异常值处理。使用describe()进行统计分析,通过Matplotlib和Seaborn绘图。回归和分类分析用到Scikit-learn,如LinearRegression和RandomForestClassifier。
114 3
|
7月前
|
Python
NumPy 是 Python 中的一个重要的科学计算包,其核心是一个强大的 N 维数组对象 Ndarray
【6月更文挑战第18天】NumPy的Ndarray是科学计算的核心,具有ndim(维度数)、shape(各维度大小)、size(元素总数)和dtype(数据类型)属性。方法包括T(转置)、ravel()(扁平化)、reshape()(改变形状)、astype()(转换数据类型)、sum()(求和)及mean()(计算平均值)。更多属性和方法如min/max等可在官方文档中探索。
68 5
|
6月前
|
数据处理 Python
数据科学进阶之路:Pandas与NumPy高级操作详解与实战演练
【7月更文挑战第13天】探索数据科学:Pandas与NumPy提升效率的高级技巧** - Pandas的`query`, `loc`和`groupby`用于复杂筛选和分组聚合,例如筛选2023年销售额超1000的记录并按类别计总销售额。 - NumPy的广播和向量化运算加速大规模数据处理,如快速计算两个大数组的元素级乘积。 - Pandas DataFrame基于NumPy,二者协同加速数据处理,如将DataFrame列转换为NumPy数组进行标准化再回写,避免链式赋值。 掌握这些高级操作,实现数据科学项目的效率飞跃。
71 0
|
6月前
|
存储 索引 Python
NumPy 教程 之 NumPy Ndarray 对象 6
NumPy的ndarray对象是多维数组,存储同类型元素,以0开始索引。包括数据指针、数据类型dtype、形状元组和跨度元组。创建使用`numpy.array()`,如`a = np.array([1, 2, 3], dtype=complex)`。内存布局可为C式行优先或F式列优先。
31 0
|
8月前
|
存储 测试技术 程序员
【Python】—— NumPy基础及取值操作
【Python】—— NumPy基础及取值操作
|
7月前
|
机器学习/深度学习 人工智能 IDE
人工智能平台PAI操作报错合集之交互式建模(DSW)环境中,numpy模块如何正确安装
阿里云人工智能平台PAI (Platform for Artificial Intelligence) 是阿里云推出的一套全面、易用的机器学习和深度学习平台,旨在帮助企业、开发者和数据科学家快速构建、训练、部署和管理人工智能模型。在使用阿里云人工智能平台PAI进行操作时,可能会遇到各种类型的错误。以下列举了一些常见的报错情况及其可能的原因和解决方法。