Numpy基础一

Numpy(Numerical Python的简称)是高性能科学计算和数据分析的基础包。它是我们课程所介绍的其他高级工具的构建基础。

其部分功能如下:

  • ndarray, 一个具有复杂广播能力的快速且节省空间的多维数组。
  • 对于整组数据进行快速的运算,无需编写循环。
  • 用于读写磁盘数据的工具以及用于操作内容映射文件的工具。
  • 用于集成由C, C++等语言编写的代码的工具。

Numpy本身并没有提供那么多高级的数据分析功能,理解Numpy数组以及面向数组的计算将有助于我们更加高效的使用pandas之类的工具。

2.1 创建数组


2.1.1 ndarray概述

Numpy最重要的一个特点就是其N纬数组对象(即ndarray),该对象是一个快速而灵活的大数据集容器。你可以利用这种数组对整块的数据执行一些数学运算。

ndarray是一个通用的同构数据多维容器,其中的所有元素必须是相同类型的。每个数组都有一个shape(表示各维度大小的元组)和一个dtype(表示数组数据类型的对象):

我们将会介绍Numpy数组的基本用法,虽然说大多数数据分析工作不需要深入理解Numpy,但精通面向数组的编程和思维方式是成为Python科学计算牛人的一大关键步骤。

注意: 我们将依照标准的Numpy约定,即总是使用import numpy as np. 当然你也可以为了不写np,而直接在代码中使用from numpy import *, 但是建议你最好还是不要养成这样的坏习惯。

2.1.2 创建ndarray

创建数组最简单的方法就是使用array函数。它接收一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组。

1. array函数创建数组

import numpy as np

ndarray1 = np.array([1, 2, 3, 4])
ndarray2 = np.array(list('abcdefg'))
ndarray3 = np.array([[11, 22, 33, 44], [10, 20, 30, 40]])

468490-18af8b7d6c6d0a29.png
image.png

2. zeros和zeros_like创建数组

用于创建数组,数组元素默认值是0. 注意:zeros_linke函数只是根据传入的ndarray数组的shape来创建所有元素为0的数组,并不是拷贝源数组中的数据.

ndarray4 = np.zeros(10)
ndarray5 = np.zeros((3, 3))
ndarray6 = np.zeros_like(ndarray5)  # 按照 ndarray5 的shape创建数组
# 打印数组元素类型
print("以下为数组类型:")
print('ndarray4:', type(ndarray4))
print('ndarray5:', type(ndarray5))
print('ndarray6:', type(ndarray6))
print("-------------")
print("以下为数组元素类型:")
print('ndarray4:', ndarray4.dtype)
print('ndarray5:', ndarray5.dtype)
print('ndarray6:', ndarray6.dtype)
print("-------------")
print("以下为数组形状:")
print('ndarray4:', ndarray4.shape)
print('ndarray5:', ndarray5.shape)
print('ndarray6:', ndarray6.shape)

468490-d0e451d3898a7512.png
image.png

3. ones和ones_like创建数组

用于创建所有元素都为1的数组.ones_like用法同zeros_like用法.

# 创建数组,元素默认值是0
ndarray7 = np.ones(10)
ndarray8 = np.ones((3, 3))
# 修改元素的值
ndarray8[0][1] = 999
ndarray9 = np.ones_like(ndarray5)  # 按照 ndarray5 的shape创建数组

468490-c54da5e604575a64.png
image.png

4. empty和empty_like创建数组

用于创建空数组,空数据中的值并不为0,而是未初始化的随机值.

ndarray10 = np.empty(5)
ndarray11 = np.empty((2, 3))
ndarray12 = np.empty_like(ndarray11)

468490-11fc2625aab11bde.png
image.png

5. arange创建数组

arange函数是python内置函数range函数的数组版本.

# 产生0-9共10个元素
ndarray13 = np.arange(10)
# 产生从10-19共10个元素
ndarray14 = np.arange(10, 20)
# 产生10 12 14 16 18, 2为step
ndarray15 = np.arange(10, 20, 2)
# ndarray15的形状
print('ndarray14的形状:', ndarray14.shape)
# 将其形状改变为(2, 5)
ndarray14.reshape((2, 5))

468490-0a0a7191c6b7c516.png
image.png

6. eys创建对角矩阵数组

该函数用于创建一个N*N的矩阵,对角线为1,其余为0.

ndarray16 = np.eye(5)

468490-484ba4bfbff9ed52.png
image.png

2.2 数据类型


我们可以通过ndarray的dtype来打印数组中元素的类型. ndarray常见的数据类型如下:

类型 类型代码 说明
int8、uint8 i1、u1 有符号和无符号的8位(1个字节长度)整型
int16、uint16 i2、u2 有符号和无符号的16位(2个字节长度)整型
int32、uint32 i4、u4 有符号和无符号的32位(4个字节长度)整型
float16 f2 半精度浮点数
float32 f4或f 标准单精度浮点数
float64 f8或d 双精度浮点数
bool ? 布尔类型
object O Python对象类型
unicode_ U 固定长度的unicode类型,跟字符串定义方式一样
import numpy as np

ndarray1 = np.array([1, 2, 3, 4])
ndarray2 = np.array(list('abcdefg'))
ndarray3 = np.array([True, False, False, True])
class Person(object):
    pass
ndarray4 = np.array([Person(), Person(), Person()])

468490-b4f0a8a4ed3cc145.png
image.png

使用astype函数转换数组类型

ndarray5 = np.array([1, 2, 3, 4, 5])
# 类型转换完毕返回新的数组
ndarray6 = ndarray5.astype(np.float32)

# 如果浮点数转换为整数,则小数部分将会被截断
ndarray7 = np.array([1.1, 2.2, 3.3, 4.4])
ndarray8 = ndarray7.astype(np.int32)

# 如果某些字符串数组表示的全是数字,也可以用astype将其转换为数值类型
ndarray9 = np.array(['10', '20', '30', '40'])
ndarray10 = ndarray9.astype(np.int32)

468490-114c789382abff45.png
image.png

2.3 数组运算


不需要循环即可对数据进行批量运算,叫做矢量化运算. 不同形状的数组之间的算数运算,叫做广播.

import numpy as np

ndarray1 = np.array([1, 2, 3, 4, 5])
ndarray2 = np.array([3, 4, 5, 6, 7])

# 数组和数组之间的运算
ndarray3 = ndarray1 * ndarray2
ndarray4 = ndarray1 + ndarray2

# 数组和数字值之间的运算
ndarray5 = ndarray1 + 100
ndarray6 = 5 / ndarray1

# 多维数组和多维数组之间的运算
ndarray7 = np.arange(9).reshape((3, 3))
ndarray8 = np.arange(9).reshape((3, 3))
ndarray9 = ndarray7 + ndarray8 

# 一维数组和多维数组之间运算
ndarray10 = np.arange(3)
ndarray11 = np.arange(6).reshape((2, 3))
ndarray12 = ndarray10 + ndarray11

468490-ce9a358aaeffed58.png
image.png

Numpy数组的索引是一个内容丰富的主题,因为选取数据子集或单个元素的方式有很多。一维数组很简单。从表面上看,它们和Python列表的功能差不多。

2.4.1 数组索引和切片基本用法

import numpy as np

ndarray1 = np.arange(10)
ndarray2 = np.arange(15).reshape((3, 5))

468490-ec488a299cff7f0a.png
image.png

注意:

  1. 当把一个数字值赋值给一个切片时,该值会自动传播到整个选区。跟列表的区别在于,数组切片是原始数组的视图,这意味着数据不会被赋值,视图上的任何修改都会直接反应到源数组上.
  2. 大家可能对此感到不解,由于Numpy被设计的目的是处理大数据,如果Numpy将数据复制来复制去的话会产生何等的性能和内存问题.
  3. 如果要得到一个切片副本的话,必须显式进行复制操作.
import numpy as np

ndarray1 = np.arange(10)
print('ndarray1->', ndarray1)
print('ndarray1[3]->', ndarray1[3])
print('ndarray1[3]->', ndarray1[2:5])
print('--------------------------')

ndarray2 = np.arange(15).reshape((3, 5))
print('ndarray2->')
print(ndarray2)
print('ndarray2[2][1] ->', ndarray2[2][1]) 
print('ndarray2[2, 1]->', ndarray2[2, 1])
print('ndarray2[:2][:1]-> ', ndarray2[:2][:1])
print('ndarray2[:2, :2]-> ')
print(ndarray2[:2, :2])
print('ndarray2[2, 1:3]-> ', ndarray2[2, 1:3])
print('ndarray2[:2, 1]-> ', ndarray2[:2, 1])

468490-0d80e8b01e44bcbb.png
image.png

提示

ndarray2[:2][:1]->  [[0 1 2 3 4]]
ndarray2[:2] ->[[0 1 2 3 4]
 [5 6 7 8 9]]
ndarray2[:2][0:1]-> [[0 1 2 3 4]]

2.4.2 数组花式索引

import numpy as np
ndarray1 = np.empty((8, 4))
for i in range(8):
    ndarray1[i] = np.arange(i, i + 4)

# 选取特定的子集,参数为列表
ret1 = ndarray1[[0, 1, 6, 7]]

# 使用负数索引会从末尾开始选取行
ret2 = ndarray1[[-1, 0, -2]]

# 一次传入多个数组
ret3 = ndarray1[[1, 3, 5], [1, 2, 3]]
ret4 = ndarray1[[1, 3, 5]][[1, 2]]

# 获取选区数据
ret5 = ndarray1[[1, 3, 5]][:, [1, 2, 3]]
ret6 = ndarray1[np.ix_([1, 2, 4], [1, 2, 3])]

468490-caa14b57654edba4.png
image.png

2.4.3 布尔型索引

1. 布尔类型基本用法:
import numpy as np

names = np.array(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'])
data = np.arange(35).reshape((7, 5))
# 数组中每一个元素都进行==运算,返回一个数组
mask = names == 'aaa'

468490-4c98fb3281e8c99b.png
image.png
2. 布尔类型数组跟切片、整数混合使用
import numpy as np

names = np.array(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'])
data = np.arange(35).reshape((7, 5))

ret1 = data[names == 'ccc']

# 布尔类型数组和整数混合使用
ret2= data[names == 'ccc', 2]

# 布尔类型数组和切片混合使用
ret3= data[names == 'ccc', 1:]

468490-70a11e30df3bbaa7.png
image.png
3. 使用不等于!=,使用(~)对条件否定
import numpy as np

names = np.array(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'])
data = np.arange(35).reshape((7, 5))

ret1 = data[names != 'ccc']
ret2 = data[~(names == 'ccc')]
ret3 = data[~(names > 'ccc')]

468490-bfffd1e8302593f8.png
image.png
4. 使用&(和)、|(或)组合多个布尔条件

注意: Python的关键字and、or在布尔数组中无效, 不能用来组合多个条件.

import numpy as np

names = np.array(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'])
data = np.arange(35).reshape((7, 5))

# 注意,Python的关键字and、or在布尔数组中无效
ret1 = data[(names == 'aaa') | (names == 'ccc')]
ret2 = data[(names > 'ddd') | (names == 'aaa')]
ret3 = data[(names < 'eee') & (names > 'bbb') ]

468490-726a5a87ed5ad723.png
image.png
5. 使用布尔类型数组设置值是一种经常用到的手段
import numpy as np

ndarray1 = np.arange(5)
ndarray2 = np.arange(16).reshape((4, 4))
names = np.array(['aaa', 'bbb', 'ccc', 'ddd'])

# 将数组ndarray1中所有大于5的元素设置成666
ndarray1[ndarray1 > 2] = 8

# 将ndarray2的aaa这一行所有的元素设置为0
ndarray2[names == 'aaa'] = 0
# 将ndarray2的bbb这一行2位置往后所有的元素设置为1
ndarray2[names == 'bbb', 2:] = 1
# 将ndarray2的ccc ddd这2行所有的元素设置为2
ndarray2[(names == 'ccc') | (names == 'ddd')] = 2

468490-4c45b10a46d8dabb.png
image.png
6. np.where用法

已知有两个数组: ndarray1 = np.array([6, 7, 8, 6, 8, 3, 4, 5, 8, 7]) ndarray2 = np.array([3, 5, 3, 7, 2, 1, 2, 2, 7, 4]) 以此对比数组中对应位置的值,取出大的值,组成新的数组.

import numpy as np

# 创建两个数组
ndarray1 = np.array([6, 7, 8, 6, 8, 3, 4, 5, 8, 7])
ndarray2 = np.array([3, 5, 3, 7, 2, 1, 2, 2, 7, 4])
# 比较条件
result1 = [ n1 if c else n2 for n1, n2, c in zip(ndarray1, ndarray2, ndarray1 > ndarray2) ]
# 这里也可以使用numpy提供的where函数
# 使用格式为: result = np.where(条件, 值1, 值2)
result2 = np.where(ndarray1 > ndarray2, ndarray1, ndarray2)

468490-cf8c414b43284874.png
image.png

课堂小练习:

  • 已知数组: ndarray3 = np.arange(32).reshape((8, 4)) 8行4列元素数组.元素从左向右从上至下依次0~31.
  • 将数组中所有大于20的元素,替换为666.
  • 将数组中所有大于13, 并且小于17的元素替换为888.
import numpy as np

ndarray3 = np.arange(32).reshape((8, 4))
# 将大于20的元素替换成666
ret1 = np.where(ndarray3 > 20, 666, ndarray3)
# 将大于13,并且小于17的元素替换成100
ret2 = np.where(ndarray3 > 13, np.where(ndarray3 < 17, 100, ndarray3), ndarray3)

468490-bfb0e2d99ae3e630.png
image.png

猜你喜欢

转载自blog.csdn.net/weixin_33717117/article/details/87049528