Numpy 入门
Numpy简介
- 官网链接:http://www.numpy.org/
- NumPy是Python语言的一个扩充程序库。支持
高级大量的维度数组与矩阵运算
,此外也针对数组运算提供大量的数学函数库
Numpy的基本功能
- 快速高效的多维数组对象ndarray
- 用于对数组执行元素级计算以及直接对数组执行数学运算的函数
- 用于读写硬盘上基于数组的数据集的工具
- 线性代数运算、傅里叶变换,以及随机数生成
- 用于将C、C++、Fortran代码集成到Python的工具
- 除了为Python提供快速的数组处理能力,NumPy在数据分析方面还有另外一个主要作用,即作为在算法之间传递数据的容器
效率对比
- 三种数据结构:list / array / numpy.array
- 三种方法求和:for / sum / numpy.sum
import timeit
from __future__ import print_function#使用for循环进行求和运算
common_for = """
for d in data:s += d
"""
#使用自带的sum函数完成求和运算
common_sum = """
sum(data)
"""
#使用numpy求和函数进行求和运算
common_numpy_sum = """
numpy.sum(data)
"""
#list容器的读取速度
def timeit_list(n, loops):list_setup = """
import numpy
data = [1] * {}
s = 0
""".format(n)print("")print("list-for:" ,timeit.timeit(common_for, list_setup, number = loops) )print("list-sum:" ,timeit.timeit(common_sum, list_setup, number = loops) )print("list-numpy-sum:" ,timeit.timeit(common_numpy_sum, list_setup, number = loops))#array容器的读取速度
def timeit_array(n, loops):array_setup = """
import numpy
import array
data = array.array('L', [1] * {})
s = 0
""".format(n)print("")print("array-for:",timeit.timeit(common_for, array_setup, number = loops) )print("array-sum:",timeit.timeit(common_sum, array_setup, number = loops) )print("array-numpy-sum:",timeit.timeit(common_numpy_sum, array_setup, number = loops) )
#numpy容器的读取速度
def timeit_numpy(n, loops):numpy_setup = """
import numpy
data = numpy.array([1] * {})
s = 0
""".format(n)print("")print("numpy-for:",timeit.timeit(common_for, numpy_setup, number = loops))print("numpy-sum:",timeit.timeit(common_sum, numpy_setup, number = loops))print("numpy-numpy-sum:",timeit.timeit(common_numpy_sum, numpy_setup, number = loops))if __name__ == '__main__':timeit_list(50000, 500)timeit_array(50000, 500)timeit_numpy(50000, 500)
list-for: 0.521558879381
list-sum: 0.0727958134364
list-numpy-sum: 0.724915150295array-for: 1.15259834089
array-sum: 0.723641693604
array-numpy-sum: 2.95501856283numpy-for: 2.08122844624
numpy-sum: 1.57353423058
numpy-numpy-sum: 0.0123528427923
*从上面的结果我们可以得到:numpy数据类型和numpy提供的数据处理函数的效率是最高的,但是把numpy的数据处理函数应用于其他的非numpy数据结构中,其效率往往不是很高。
NumPy的ndarray 创建ndarray
- 数组创建函数
# -*- coding: utf-8 -*-import numpy as np
from __future__ import print_functionprint ('使用普通一维数组生成NumPy一维数组')
data = [6, 7.5, 8, 0, 1]
arr = np.array(data)
print (arr)
print('打印元素类型')
print(arr.dtype) #提供了dtype变量查看数据的类型
print()print('使用普通二维数组生成NumPy二维数组')
data = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr = np.array(data)
print (arr)
print ('打印数组维度')
print (arr.shape)
print()print ('使用zeros/empty')
print ("np.zeros:",np.zeros(10)) # 生成包含10个0的一维数组
print ("np.zeros:",np.zeros((3, 6))) # 生成3*6的二维数组,表示数组维度的参数使用的是元组
print ("np.empty:",np.empty((2, 3, 2))) # 生成2*3*2的三维数组,所有元素未初始化。
print()print( '使用arrange生成连续元素')
print (np.arange(15)) # [0, 1, 2, ..., 14]print("使用ones_like,zeros_like和empty_like创建Numpy数组")
print("np.ones_like:",np.ones_like(np.zeros((3, 6))))
print("np.zeros_like:",np.zeros_like(np.ones((2,3))))
print("np.empty_like:",np.empty_like(np.ones((2,3))))
使用普通一维数组生成NumPy一维数组
[ 6. 7.5 8. 0. 1. ]
打印元素类型
float64使用普通二维数组生成NumPy二维数组
[[1 2 3 4][5 6 7 8]]
打印数组维度
(2L, 4L)使用zeros/empty
np.zeros: [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
np.zeros: [[ 0. 0. 0. 0. 0. 0.][ 0. 0. 0. 0. 0. 0.][ 0. 0. 0. 0. 0. 0.]]
np.empty: [[[ 0. 0.][ 0. 0.][ 0. 0.]][[ 0. 0.][ 0. 0.][ 0. 0.]]]使用arrange生成连续元素
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
使用ones_like,zeros_like和empty_like创建Numpy数组
np.ones_like: [[ 1. 1. 1. 1. 1. 1.][ 1. 1. 1. 1. 1. 1.][ 1. 1. 1. 1. 1. 1.]]
np.zeros_like: [[ 0. 0. 0.][ 0. 0. 0.]]
np.empty_like: [[ 1. 1. 1.][ 1. 1. 1.]]
NumPy的ndarray NumPy数据类型
- NumPy数据类型 I
- NumPy数据类型 II
- 创建ndarray时指定dtype类型
- 使用astype显示转换类型
# -*- coding: utf-8 -*-import numpy as np
from __future__ import print_functionprint ('生成数组时指定数据类型')
arr = np.array([1, 2, 3], dtype = np.float64) # 使用dtype关键字指定数据的类型
print (arr.dtype)
arr = np.array([1, 2, 3], dtype = np.int32)
print (arr.dtype)
print()print ('使用astype复制数组并转换数据类型')
int_arr = np.array([1, 2, 3, 4, 5])
float_arr = int_arr.astype(np.float)#使用astype转换数据的类型
print (int_arr.dtype)
print (float_arr.dtype)
print()print ('使用astype将float转换为int时小数部分被舍弃')
float_arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
int_arr = float_arr.astype(dtype = np.int)
print (int_arr)
print()print ('使用astype把字符串转换为数组,如果失败抛出异常。')
str_arr = np.array(['1.25', '-9.6', '42'], dtype = np.string_)#一定要注意后面的下划线
float_arr = str_arr.astype(dtype = np.float)
print (float_arr)
print()print( 'astype使用其它数组的数据类型作为参数')
int_arr = np.arange(10)
float_arr = np.array([.23, 0.270, .357, 0.44, 0.5], dtype = np.float64)
print (int_arr.astype(float_arr.dtype))
print (int_arr[0], int_arr[1]) # astype做了复制,数组本身不变。
生成数组时指定数据类型
float64
int32使用astype复制数组并转换数据类型
int32
float64使用astype将float转换为int时小数部分被舍弃
[ 3 -1 -2 0 12 10]使用astype把字符串转换为数组,如果失败抛出异常。
[ 1.25 -9.6 42. ]astype使用其它数组的数据类型作为参数
[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
0 1
NumPy的ndarray 数组和标量之间的运算
- 不用编写循环即可对数据执行批量运算
- 大小相等的数组之间的任何算术运算都会将运算应用到元素级
- 数组与标量的算术运算也会将那个标量值传播到各个元素
# -*- coding: utf-8 -*-import numpy as np
from __future__ import print_function# 数组乘法/减法,对应元素相乘/相减。
arr = np.array([[1.0, 2.0, 3.0], [4., 5., 6.]])
print ('数组乘法:',arr * arr) #对应元素相乘
print ('数组减法:',arr - arr) #对应元素相减
print()# 标量操作作用在数组的每个元素上(广播作用)
arr = np.array([[1.0, 2.0, 3.0], [4., 5., 6.]])
print ("数组除法:",1 / arr)#对数组中的每个元素最除法
print ("开根号:",arr ** 0.5) # 开根号
print ("数组加法:",arr + 0.5) # 加法
数组乘法: [[ 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]]
数组加法: [[ 1.5 2.5 3.5][ 4.5 5.5 6.5]]
NumPy的ndarray 基本的索引和切片
- 索引原理
- 切片原理
# -*- coding: utf-8 -*-import numpy as np
from __future__ import print_function# 通过索引访问二维数组某一行或某个元素
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("数组的维度为:" , arr.shape)
print (arr[2]) #数组的第3行
print (arr[0][2]) #数组的第一行第三列的元素
print (arr[0, 2]) # 普通Python数组不能用。数组的diy
print()# 对更高维数组的访问和操作
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr)
print("数组的维度为:" , arr.shape)
print (arr[0]) # 结果是个2维数组:[[1,2,3],[4,5,6]],相当于减去了一个中括号,然后选独立的部分
print (arr[1, 0]) # 结果是个1维数组:[7,8,9]
old_values = arr[0].copy() # 复制arr[0]的值(此处必须使用copy方法,进行完全的复制,这是一个坑)
arr[0] = 42 # 把arr[0]所有的元素都设置为同一个值
print (arr)
arr[0] = old_values # 把原来的数组写回去
print (arr)
print()print ('使用切片访问和操作数组')
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print("数组的维度为:" , arr.shape)
print (arr[1:6]) # 打印元素arr[1]到arr[5]arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print (arr[:2]) # 打印第1、2行
print (arr[:2, 1:]) # 打印第1、2行,第2、3列
print (arr[:, :1]) # 打印第一列的所有元素
arr[:2, 1:] = 0 # 第1、2行,第2、3列的元素设置为0
print (arr)
数组的维度为: (3L, 3L)
[7 8 9]
3
3[[[ 1 2 3][ 4 5 6]][[ 7 8 9][10 11 12]]]
数组的维度为: (2L, 2L, 3L)
[[1 2 3][4 5 6]]
[7 8 9]
[[[42 42 42][42 42 42]][[ 7 8 9][10 11 12]]]
[[[ 1 2 3][ 4 5 6]][[ 7 8 9][10 11 12]]]使用切片访问和操作数组
数组的维度为: (10L,)
[2 3 4 5 6]
[[1 2 3][4 5 6]]
[[2 3][5 6]]
[[1][4][7]]
[[1 0 0][4 0 0][7 8 9]]
数组的索引和切片非常重要:
- 看一个numpy的数组是几维的,则可以数数组表示中中括号的最大个数,如果最大的个数为3个,则该数组为3维
- 切片中的[a,b]是一个左闭右开的区间,数组的初始坐标都从0开始计算
- 多维数组可以看成多个低位数组的行排列。
NumPy的ndarray 布尔型索引
- 布尔型数组的长度必须跟被索引的轴长度一致
- 可以将布尔型数组跟切片、整数(或整数序列)混合使用
from __future__ import print_function
import numpy as np
import numpy.random as np_randomprint ('使用布尔数组作为索引')
name_arr = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
rnd_arr = np_random.randn(7, 4) # 随机7*4数组
print (rnd_arr)
print (name_arr == 'Bob') # 返回布尔数组,元素等于'Bob'为True,否则False。
print (rnd_arr[name_arr == 'Bob']) # 利用布尔数组选择行,选出数组的第0行和第3行
print (rnd_arr[name_arr == 'Bob', :2]) # 增加限制打印列的范围,选出数组的第0行和第3行的第0列和第1列
print (rnd_arr[~(name_arr == 'Bob')]) # 对布尔数组的内容取反
mask_arr = (name_arr == 'Bob') | (name_arr == 'Will') # 逻辑运算混合结果
print (rnd_arr[mask_arr])
rnd_arr[name_arr != 'Joe'] = 7 # 先布尔数组选择行,然后把每行的元素设置为7。
print (rnd_arr)
使用布尔数组作为索引
[[-0.1084202 -0.40555507 -0.42840017 -1.21241416][ 0.52151894 -0.06591568 -1.13705598 0.30621352][-2.15443164 -0.72205865 0.4932395 -0.91993207][-0.50711626 2.11309111 -1.67907697 0.19700825][ 1.56799018 1.23573277 -1.57973114 1.20070367][ 0.36692194 -0.1980408 0.02920299 1.40526864][ 1.38148029 0.95975349 0.19451545 -1.22338701]]
[ True False False True False False False]
[[-0.1084202 -0.40555507 -0.42840017 -1.21241416][-0.50711626 2.11309111 -1.67907697 0.19700825]]
[[-0.1084202 -0.40555507][-0.50711626 2.11309111]]
[[ 0.52151894 -0.06591568 -1.13705598 0.30621352][-2.15443164 -0.72205865 0.4932395 -0.91993207][ 1.56799018 1.23573277 -1.57973114 1.20070367][ 0.36692194 -0.1980408 0.02920299 1.40526864][ 1.38148029 0.95975349 0.19451545 -1.22338701]]
[[-0.1084202 -0.40555507 -0.42840017 -1.21241416][-2.15443164 -0.72205865 0.4932395 -0.91993207][-0.50711626 2.11309111 -1.67907697 0.19700825][ 1.56799018 1.23573277 -1.57973114 1.20070367]]
[[ 7. 7. 7. 7. ][ 0.52151894 -0.06591568 -1.13705598 0.30621352][ 7. 7. 7. 7. ][ 7. 7. 7. 7. ][ 7. 7. 7. 7. ][ 0.36692194 -0.1980408 0.02920299 1.40526864][ 1.38148029 0.95975349 0.19451545 -1.22338701]]
NumPy的ndarray 花式索引
- 花式索引(Fancy indexing)是一个NumPy术语,它指的是利用整数数组进行索引
- 一次传入多个索引数组会有一点特别。它返回的是一个一维数组,其中的元素对应各个索引元组
# -*- coding: utf-8 -*-import numpy as npprint ('Fancy Indexing: 使用整数数组作为索引')
arr = np.empty((8, 4))
for i in range(8):arr[i] = i
print (arr)
print()
print (arr[[4, 3, 0, 6]]) # 打印arr[4]、arr[3]、arr[0]和arr[6]。
print()
print (arr[[-3, -5, -7]]) # 打印arr[3](8-5)、arr[5](8-3)和arr[1](8-7)行
print()
arr = np.arange(32).reshape((8, 4)) # 通过reshape变换成二维数组
print(arr)
print()
print (arr[[1, 5, 7, 2], [0, 3, 1, 2]]) # 打印arr[1, 0]、arr[5, 3],arr[7, 1]和arr[2, 2]
print()
print (arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]] ) # 1572行的0312列
print()
print (arr[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])]) # 可读性更好的写法
Fancy Indexing: 使用整数数组作为索引
[[ 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.]][[ 4. 4. 4. 4.][ 3. 3. 3. 3.][ 0. 0. 0. 0.][ 6. 6. 6. 6.]][[ 5. 5. 5. 5.][ 3. 3. 3. 3.][ 1. 1. 1. 1.]][[ 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][[ 4 7 5 6][20 23 21 22][28 31 29 30][ 8 11 9 10]][[ 4 7 5 6][20 23 21 22][28 31 29 30][ 8 11 9 10]]
NumPy的ndarray 数组转置和轴对换
- 一维/二维数组转置
- 高维数组轴对换
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('转置矩阵')
arr = np.arange(15).reshape((3, 5))
print (arr)
print (arr.T)
print()print ('转置矩阵做点积')
arr = np_random.randn(6, 3)
print (np.dot(arr.T, arr))
print()print ('高维矩阵转换')
arr = np.arange(16).reshape((2, 2, 4))
print (arr)
'''
详细解释:
arr数组的内容为
- a[0][0] = [0, 1, 2, 3]
- a[0][1] = [4, 5, 6, 7]
- a[1][0] = [8, 9, 10, 11]
- a[1][1] = [12, 13, 14, 15]
transpose的参数为坐标,正常顺序为(0, 1, 2, ... , n - 1),
现在传入的为(1, 0, 2)代表a[x][y][z] = a[y][x][z],第0个和第1个坐标互换。
- a'[0][0] = a[0][0] = [0, 1, 2, 3]
- a'[0][1] = a[1][0] = [8, 9, 10, 11]
- a'[1][0] = a[0][1] = [4, 5, 6, 7]
- a'[1][1] = a[1][1] = [12, 13, 14, 15]
'''
print (arr.transpose((1, 0, 2)))
print (arr.swapaxes(1, 2)) # 直接交换第1和第2个坐标
转置矩阵
[[ 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]]转置矩阵做点积
[[ 6.36174171 2.42894214 0.43029091][ 2.42894214 1.62972705 -0.47956574][ 0.43029091 -0.47956574 8.71542488]]高维矩阵转换
[[[ 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]]]
[[[ 0 4][ 1 5][ 2 6][ 3 7]][[ 8 12][ 9 13][10 14][11 15]]]
NumPy的ndarray 快速的元素级数组函数
- 一元函数 I
- 一元函数 II
- 二元函数 I
- 二元函数 II
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint("一元数组I")print("计算整数、浮点数或复数的绝对值")
a = - np.arange(32).reshape((4,8))
print(abs(a))
# print(fabs(a))print ('求平方根')
arr = np.arange(10)
print (np.sqrt(arr))
print()print("计算各元素的平方")
arr = np.empty((8,3))
for i in range(8):arr[i] = i
print(arr)print ('数组比较')
x = np_random.randn(8)
y = np_random.randn(8)
print (x)
print (y)
print (np.maximum(x, y))
print()print ('使用modf函数把浮点数分解成整数和小数部分')
arr = np_random.randn(7) * 5 # 统一乘5
print (np.modf(arr))
一元数组I
计算整数、浮点数或复数的绝对值
[[ 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]]
求平方根
[ 0. 1. 1.41421356 1.73205081 2. 2.236067982.44948974 2.64575131 2.82842712 3. ]计算各元素的平方
[[ 0. 0. 0.][ 1. 1. 1.][ 2. 2. 2.][ 3. 3. 3.][ 4. 4. 4.][ 5. 5. 5.][ 6. 6. 6.][ 7. 7. 7.]]
数组比较
[-0.68111525 0.14478485 -1.90946169 -1.44911281 0.83112239 -0.70184092-0.87512769 0.86081927]
[-1.76259424 -0.23016572 0.3511254 -1.44010152 0.27544984 0.27675796-1.0203264 -1.95418324]
[-0.68111525 0.14478485 0.3511254 -1.44010152 0.83112239 0.27675796-0.87512769 0.86081927]使用modf函数把浮点数分解成整数和小数部分
(array([-0.5637991 , -0.97362809, -0.35885139, 0.52156623, 0.31868237,-0.62290837, 0.18592416]), array([-4., -6., -0., 4., 0., -2., 3.]))
利用数组进行数据处理
- NumPy数组使你可以将许多种数据处理任务表述为简洁的数组表达式(否则需要编写循环)。用数组表达式代替循环的做法,通常被称为矢量化。
- 矢量化数组运算要比等价的纯Python方式快上一两个数量级
# -*- coding: utf-8 -*-from __future__ import print_function
import matplotlib.pyplot as plt
import numpy as np
import pylabpoints = np.arange(-5, 5, 0.01) # 生成100个点
xs, ys = np.meshgrid(points, points) # xs, ys互为转置矩阵
print (xs)
print (ys)
z = np.sqrt(xs ** 2 + ys ** 2)
print (z)
# 画图
plt.imshow(z, cmap = plt.cm.gray);
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
pylab.show()
利用数组进行数据处理 将条件逻辑表述为数组运算
- 列表推导的局限性
- 纯Python代码,速度不够快
- 无法应用于高维数组
- where和where的嵌套
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_random'''
关于zip函数的一点解释,zip可以接受任意多参数,然后重新组合成1个tuple列表。
zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
返回结果:[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
'''
print ('通过真值表选择元素')
x_arr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
y_arr = 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(x_arr, y_arr, cond)] # 通过列表推到实现
print (result)
print (np.where(cond, x_arr, y_arr)) # 使用NumPy的where函数
print()print ('更多where的例子')
arr = np_random.randn(4, 4)
print (arr)
print (np.where(arr > 0, 2, -2)) #数组中大于0的值,赋值为2,小于0的赋值为-2
print (np.where(arr > 0, 2, arr)) #数组中大于0的值,赋值为2,小于0的不变
print()print ('where嵌套')
cond_1 = np.array([True, False, True, True, False])
cond_2 = np.array([False, True, False, True, False])
# 传统代码如下
result = []
for i in xrange(len(cond)):if cond_1[i] and cond_2[i]:result.append(0)elif cond_1[i]:result.append(1)elif cond_2[i]:result.append(2)else:result.append(3)
print (result)
# np版本代码
result = np.where(cond_1 & cond_2, 0, \np.where(cond_1, 1, np.where(cond_2, 2, 3)))
print (result)
通过真值表选择元素
[1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]
[ 1.1 2.2 1.3 1.4 2.5]更多where的例子
[[-0.79654157 1.3048699 -0.16649545 -0.67927283][ 1.03154654 -0.84729219 0.88878329 1.22445457][ 0.21591511 -1.76778359 0.64909628 0.9290586 ][-1.07820837 0.77882286 -0.85592141 0.73408195]]
[[-2 2 -2 -2][ 2 -2 2 2][ 2 -2 2 2][-2 2 -2 2]]
[[-0.79654157 2. -0.16649545 -0.67927283][ 2. -0.84729219 2. 2. ][ 2. -1.76778359 2. 2. ][-1.07820837 2. -0.85592141 2. ]]where嵌套
[1, 2, 1, 0, 3]
[1 2 1 0 3]
利用数组进行数据处理 数学和统计方法
- 数学和统计方法
- 标准差和方差的解释
- cumsum和cumprod的解释
- 带axis参数的统计函数
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('求和,求平均')
arr = np.random.randn(5, 4)
print (arr)
print (arr.mean())
print (arr.sum())
print (arr.mean(axis = 1)) # 对每一行的元素求平均 (0表示列 , 1表示行)
print (arr.sum(0)) # 对每一列元素求和,axis可以省略。
print()'''
cumsum:
- 按列操作:a[i][j] += a[i - 1][j]
- 按行操作:a[i][j] *= a[i][j - 1]
cumprod:
- 按列操作:a[i][j] += a[i - 1][j]
- 按行操作:a[i][j] *= a[i][j - 1]
'''
print ('cunsum和cumprod函数演示')
arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
print (arr.cumsum(0))#列不变,按行操作,第i行等于第i-1行+第i行
print (arr.cumprod(1))#行不变,按列操作,第j列等于第j-1列*第j列
求和,求平均
[[ 0.26455591 0.24469854 0.35609714 -0.91358351][-0.06096831 -1.4540408 1.52873578 -1.04853165][ 0.13539534 -0.57258895 0.01197242 -0.16440243][-0.37880532 -0.5595963 0.61614963 0.40114372][ 1.02586237 0.51157099 0.51307014 0.06042945]]
0.0258582086869
0.517164173737
[-0.01205798 -0.25870124 -0.1474059 0.01972293 0.52773324]
[ 0.98603999 -1.82995651 3.02602511 -1.66494442]cunsum和cumprod函数演示
[[ 0 1 2][ 3 5 7][ 9 12 15]]
[[ 0 0 0][ 3 12 60][ 6 42 336]]
利用数组进行数据处理 用于布尔型数组的方法
- sum对True值计数
- any和all测试布尔型数组,对于非布尔型数组,所有非0元素将会被当做True
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('对正数求和')
arr = np_random.randn(100)
print("数组为:" , arr)
print ((arr > 0).sum())
print()print ('对数组逻辑操作')
bools = np.array([False, False, True, False])
print (bools.any()) # 有一个为True则返回True
print (bools.all()) # 有一个为False则返回False
对正数求和
数组为: [-0.67957765 0.17922628 0.81893223 1.51839207 -0.53998528 -0.061346690.26828107 0.49541898 0.3968868 1.48527375 -0.92795078 0.67722850.92645474 0.82941435 -1.55900369 -0.9505581 0.55135723 -0.24448502-0.89383558 -1.04803647 1.46630771 1.05768561 -1.31654583 -0.793245111.24940464 -0.35685884 0.2880603 1.79418786 -0.06005563 -0.326561910.61529929 1.18118605 -0.67298437 -0.18722625 0.67770887 -1.855256140.21878993 0.35457737 1.26314661 -1.38037944 1.83993354 -0.76711544-0.36366676 0.4834541 -0.3258269 -0.50041094 -0.11865619 0.182630250.71411782 0.66851825 -0.53817733 0.29773314 -0.32270224 -0.28514864-0.88821182 -0.27463386 0.3208152 -0.63070493 -1.50305558 1.04202097-0.55430861 0.5475183 -0.29936811 -0.8214571 -0.05786574 0.19635782-2.4263667 0.23870753 -0.32306864 2.20755471 0.62571506 -1.620709410.03456916 0.73668574 -0.47187531 -1.40560797 0.86782166 -0.620637020.34219792 -1.06724602 -1.25501497 -0.59017057 0.33234826 -0.33625352-0.10762397 -0.14479564 -0.85080006 -0.1615957 0.00796442 1.51127179-1.50552389 -0.27143849 0.04650197 -0.17451162 -0.01494695 0.532787152.0052779 1.68621344 0.43084895 -0.86445014]
47对数组逻辑操作
True
False
利用数组进行数据处理 排序
- 直接排序
- 指定轴排序
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('一维数组排序')
arr = np_random.randn(8)
print("排序前:",arr)
arr.sort() #默认为从小到大排序
print ("排序后:",arr)
print()print ('二维数组排序')
arr = np_random.randn(5, 3)
print (arr)
arr.sort(1) # 对每一行元素做排序
print (arr)print ('找位置在5%的数字')
large_arr = np_random.randn(1000)
large_arr.sort()
print (large_arr[int(0.05 * len(large_arr))])
一维数组排序
排序前: [-1.42173589 0.48630163 -0.66291646 -0.45981918 1.9129553 1.226950490.82006022 0.92006356]
排序后: [-1.42173589 -0.66291646 -0.45981918 0.48630163 0.82006022 0.920063561.22695049 1.9129553 ]二维数组排序
[[-1.19629529 0.31347271 -1.76425575][ 0.140376 0.27033496 -0.61144276][-0.62964274 -0.19658808 -0.00377922][ 0.82857078 -0.77745588 -0.39493397][ 1.87901812 -0.03795931 0.15201365]]
[[-1.76425575 -1.19629529 0.31347271][-0.61144276 0.140376 0.27033496][-0.62964274 -0.19658808 -0.00377922][-0.77745588 -0.39493397 0.82857078][-0.03795931 0.15201365 1.87901812]]
找位置在5%的数字
-1.75964266014
利用数组进行数据处理 去重以及其它集合运算
- 去重以及其它集合运算
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint( '用unique函数去重')
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
print (sorted(set(names))) # 传统Python做法:先转为集合,去重后,在排序
print (np.unique(names))
ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
print (np.unique(ints))
print()print("计算x和y中的公共元素")
valuse = np.array([1,4,6,8,0,1,4,5])
print(np.intersect1d(values,[1,5,6]))print( '查找数组元素是否在另一数组')
values = np.array([6, 0, 0, 3, 2, 5, 6])
print (np.in1d(values, [2, 3, 6]))#判断数组value中的值是否在数组[2,3,6]中,如果在,则为true,否则为false
用unique函数去重
['Bob', 'Joe', 'Will']
['Bob' 'Joe' 'Will']
[1 2 3 4]计算x和y中的公共元素
[5 6]
查找数组元素是否在另一数组
[ True False False True True False True]
数组文件的输入输出
- 将数组以二进制格式保存到磁盘
- 存取文本文件
# -*- coding: utf-8 -*-import numpy as npprint ('数组文件读写')
arr = np.arange(10)
np.save('some_array', arr)
print (np.load('some_array.npy'))
print()print( '多个数组压缩存储')
np.savez('array_archive.npz', a = arr, b = arr)
arch = np.load('array_archive.npz')
print (arch['b'])
数组文件读写
[0 1 2 3 4 5 6 7 8 9]多个数组压缩存储
[0 1 2 3 4 5 6 7 8 9]
# -*- coding: utf-8 -*-import numpy as npprint ('读取csv文件做为数组')
arr = np.loadtxt('array_ex.txt', delimiter = ',')
print (arr)
线性代数
- 常用的numpy.linalg函数 I
- 常用的numpy.linalg函数 II
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_random
from numpy.linalg import inv, qrprint ('矩阵乘法')
x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
print (x.dot(y))
print (np.dot(x, np.ones(3)))
x = np_random.randn(5, 5)
print()print( '矩阵求逆')
mat = x.T.dot(x)
print( inv(mat)) # 矩阵求逆
print (mat.dot(inv(mat))) # 与逆矩阵相乘,得到单位矩阵。
print()print ('矩阵消元')
print (mat)
q, r = qr(mat)
print (q)
print (r)
# TODO: http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.qr.html q代表什么矩阵?
矩阵乘法
[[ 28. 64.][ 67. 181.]]
[ 6. 15.]矩阵求逆
[[ 0.5011485 0.30366035 0.02944988 0.10182832 0.37384833][ 0.30366035 1.10386855 0.51472706 0.14750528 0.33597911][ 0.02944988 0.51472706 0.49264089 0.0648786 0.02335427][ 0.10182832 0.14750528 0.0648786 0.24308276 -0.06829375][ 0.37384833 0.33597911 0.02335427 -0.06829375 0.76240877]]
[[ 1.00000000e+00 3.47790860e-16 8.91056239e-18 3.96778168e-17-2.44764394e-17][ 2.29383400e-17 1.00000000e+00 -6.05299206e-17 4.07325720e-172.32749172e-16][ -1.66416098e-17 -1.80279523e-17 1.00000000e+00 -4.81508104e-17-1.48983014e-16][ 3.02073179e-16 6.79592724e-17 -2.87171290e-17 1.00000000e+00-9.96169938e-17][ -2.42778368e-17 -8.66789085e-18 -5.19194405e-17 -3.07066395e-171.00000000e+00]]矩阵消元
[[ 4.32328254 -0.63693392 0.79671674 -2.21655667 -2.06219977][-0.63693392 2.68135504 -2.60228948 -0.91045864 -0.87114247][ 0.79671674 -2.60228948 4.64737 0.18198227 0.63005045][-2.21655667 -0.91045864 0.18198227 6.11670728 2.03045137][-2.06219977 -0.87114247 0.63005045 2.03045137 2.86931167]]
[[-0.80424283 0.05803869 0.31139518 -0.29376817 0.40811553][ 0.11848625 -0.6616017 -0.46781842 -0.44143639 0.36677518][-0.14821 0.63785055 -0.72732656 -0.20378064 0.02549494][ 0.4123371 0.28244792 0.37835796 -0.77555677 -0.07455361][ 0.38362271 0.26885784 0.10963713 0.27535309 0.83229168]]
[[-5.37559352 0.50603266 -1.32113627 4.94887402 3.39987476][ 0. -3.96219829 4.95304159 2.86334648 2.20347373][ 0. 0. -1.77673158 2.14026146 0.38994553][ 0. 0. 0. -3.16878375 0.07731411][ 0. 0. 0. 0. 1.09166069]]
随机数生成
- 部分numpy.random函数 I
- 部分numpy.random函数 II
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_random
from random import normalvariateprint ('正态分布随机数')
samples = np.random.normal(size=(4, 4))
print (samples)print ('批量按正态分布生成0到1的随机数')
N = 10
print( [normalvariate(0, 1) for _ in xrange(N)])
print (np.random.normal(size = N)) # 与上面代码等价
正态分布随机数
[[-0.50544264 -0.82576933 1.89526245 -0.58707003][ 0.2252303 -0.33877777 -0.51077759 -0.34970251][-0.47528039 0.49921574 0.94502307 -0.2377654 ][-0.36301675 -0.76251246 1.76277718 0.42690543]]
批量按正态分布生成0到1的随机数
[-1.0186591774950984, 1.866210983292114, -1.1265355424761359, 1.2576651018422442, 0.5304683236918599, -2.907445702261537, 0.4475662133447387, -1.1263633248787712, -0.46554861570035416, 0.8651894338485295]
[-0.29615892 0.15133984 -0.05640947 1.63244238 1.3805192 1.33271080.56834895 -0.15348624 -0.27670743 0.15896747]
高级应用 数组重塑
- reshape重塑数组
- -1自动推导维度大小
# -*- coding: utf-8 -*-import numpy as npprint ("将一维数组转换为二维数组")
arr = np.arange(8)
print (arr.reshape((4, 2)))
print (arr.reshape((4, 2)).reshape((2, 4))) # 支持链式操作
print()print ("维度大小自动推导")
arr = np.arange(15)
print (arr.reshape((5, -1)))
print()print ("获取维度信息并应用")
other_arr = np.ones((3, 5))
print (other_arr.shape)
print (arr.reshape(other_arr.shape))
print()print ("高维数组拉平")
arr = np.arange(15).reshape((5, 3))
print (arr.ravel())
将一维数组转换为二维数组
[[0 1][2 3][4 5][6 7]]
[[0 1 2 3][4 5 6 7]]维度大小自动推导
[[ 0 1 2][ 3 4 5][ 6 7 8][ 9 10 11][12 13 14]]获取维度信息并应用
(3L, 5L)
[[ 0 1 2 3 4][ 5 6 7 8 9][10 11 12 13 14]]高维数组拉平
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
高级应用 数组的合并和拆分
- 数组连接函数
- _r对象
- _c对象
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint( '连接两个二维数组')
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
print (np.concatenate([arr1, arr2], axis = 0)) # 将2个数组按上下进行堆叠(列形式),然后去掉中括号
print (np.concatenate([arr1, arr2], axis = 1)) # 将2个数组按作业进行排布(行形式),然后去掉中括号
print()# 所谓堆叠,参考叠盘子。。。连接的另一种表述
print ('垂直stack与水平stack')
print (np.vstack((arr1, arr2))) # 垂直堆叠,将2个数组按上下进行堆叠(列形式),然后去掉中括号
print (np.hstack((arr1, arr2))) # 水平堆叠,将2个数组按作业进行排布(行形式),然后去掉中括号
print()print ('拆分数组')
arr = np_random.randn(5, 5)
print (arr)
print ('水平拆分')
first, second, third = np.split(arr, [1, 3], axis = 0) # 列不变,按行拆分
print ('first')
print (first)
print( 'second')
print (second)
print ('third')
print (third)
print ('垂直拆分')
first, second, third = np.split(arr, [1, 3], axis = 1)# 行不变,按列拆分
print ('first')
print (first)
print ('second')
print (second)
print( 'third')
print (third)
print()# 堆叠辅助类
arr = np.arange(6)
arr1 = arr.reshape((3, 2))
arr2 = np_random.randn(3, 2)
print ('r_用于按行堆叠')
print (np.r_[arr1, arr2])
print ('c_用于按列堆叠')
print (np.c_[np.r_[arr1, arr2], arr])
print ('切片直接转为数组')
print (np.c_[1:6, -10:-5])
连接两个二维数组
[[ 1 2 3][ 4 5 6][ 7 8 9][10 11 12]]
[[ 1 2 3 7 8 9][ 4 5 6 10 11 12]]垂直stack与水平stack
[[ 1 2 3][ 4 5 6][ 7 8 9][10 11 12]]
[[ 1 2 3 7 8 9][ 4 5 6 10 11 12]]拆分数组
[[ 1.89364796 0.90294454 -1.04449259 0.05542727 -1.95040133][ 0.61216323 -0.04858817 0.62079075 2.14728789 -1.64469211][ 0.80412986 -1.1504998 0.72143456 1.2071584 0.28430334][ 0.83783665 0.46357796 -1.03665112 0.63458637 -1.47938356][-0.14603724 -1.20880463 0.37298991 -0.91002865 -0.86368792]]
水平拆分
first
[[ 1.89364796 0.90294454 -1.04449259 0.05542727 -1.95040133]]
second
[[ 0.61216323 -0.04858817 0.62079075 2.14728789 -1.64469211][ 0.80412986 -1.1504998 0.72143456 1.2071584 0.28430334]]
third
[[ 0.83783665 0.46357796 -1.03665112 0.63458637 -1.47938356][-0.14603724 -1.20880463 0.37298991 -0.91002865 -0.86368792]]
垂直拆分
first
[[ 1.89364796][ 0.61216323][ 0.80412986][ 0.83783665][-0.14603724]]
second
[[ 0.90294454 -1.04449259][-0.04858817 0.62079075][-1.1504998 0.72143456][ 0.46357796 -1.03665112][-1.20880463 0.37298991]]
third
[[ 0.05542727 -1.95040133][ 2.14728789 -1.64469211][ 1.2071584 0.28430334][ 0.63458637 -1.47938356][-0.91002865 -0.86368792]]r_用于按行堆叠
[[ 0. 1. ][ 2. 3. ][ 4. 5. ][ 0.16991136 -1.43876481][-0.98143743 -1.05678896][-0.19718503 0.13712377]]
c_用于按列堆叠
[[ 0. 1. 0. ][ 2. 3. 1. ][ 4. 5. 2. ][ 0.16991136 -1.43876481 3. ][-0.98143743 -1.05678896 4. ][-0.19718503 0.13712377 5. ]]
切片直接转为数组
[[ 1 -10][ 2 -9][ 3 -8][ 4 -7][ 5 -6]]
高级应用 元素的重复操作
- _tile
- _repeat
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('Repeat: 按元素')
arr = np.arange(3)
print (arr.repeat(3)) #以整个数组为对象。进行复制
print (arr.repeat([2, 3, 4])) # 3个元素,分别复制2, 3, 4次。长度要匹配!
print()print ('Repeat,指定轴')
arr = np_random.randn(2, 2)
print (arr)
print (arr.repeat(2, axis = 0)) # 按行repeat
print (arr.repeat(2, axis = 1)) # 按列repeat
print (arr.repeat(2, axis = 0)) # 按行repeat
print()print ('Tile: 参考贴瓷砖')#元素级别的复制
print (np.tile(arr, 2))
print (np.tile(arr, (2, 3))) # 指定每个轴的tile次数
Repeat: 按元素
[0 0 0 1 1 1 2 2 2]
[0 0 1 1 1 2 2 2 2]Repeat,指定轴
[[-0.09641823 -2.30892488][-0.47084845 -0.85517063]]
[[-0.09641823 -2.30892488][-0.09641823 -2.30892488][-0.47084845 -0.85517063][-0.47084845 -0.85517063]]
[[-0.09641823 -0.09641823 -2.30892488 -2.30892488][-0.47084845 -0.47084845 -0.85517063 -0.85517063]]
[[-0.09641823 -2.30892488][-0.09641823 -2.30892488][-0.47084845 -0.85517063][-0.47084845 -0.85517063]]Tile: 参考贴瓷砖
[[-0.09641823 -2.30892488 -0.09641823 -2.30892488][-0.47084845 -0.85517063 -0.47084845 -0.85517063]]
[[-0.09641823 -2.30892488 -0.09641823 -2.30892488 -0.09641823 -2.30892488][-0.47084845 -0.85517063 -0.47084845 -0.85517063 -0.47084845 -0.85517063][-0.09641823 -2.30892488 -0.09641823 -2.30892488 -0.09641823 -2.30892488][-0.47084845 -0.85517063 -0.47084845 -0.85517063 -0.47084845 -0.85517063]]
高级应用 花式索引的等价函数
- take
- put
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('Fancy Indexing例子代码')
arr = np.arange(10) * 100
inds = [7, 1, 2, 6]
print (arr[inds])
print()print ('使用take')
print (arr.take(inds))
print()print ('使用put更新内容')
arr.put(inds, 50)
print (arr)
arr.put(inds, [70, 10, 20, 60])
print (arr)
print()print ('take,指定轴')
arr = np_random.randn(2, 4)
inds = [2, 0, 2, 1]
print (arr)
print (arr.take(inds, axis = 1) ) # 按列take
Fancy Indexing例子代码
[700 100 200 600]使用take
[700 100 200 600]使用put更新内容
[ 0 50 50 300 400 500 50 50 800 900]
[ 0 10 20 300 400 500 60 70 800 900]take,指定轴
[[-0.02673792 -0.07054738 -1.14709723 0.53862843][ 1.36231019 -0.95801917 1.33658699 0.36900439]]
[[-1.14709723 -0.02673792 -1.14709723 -0.07054738][ 1.33658699 1.36231019 1.33658699 -0.95801917]]