一、数据绘图matplotlib

matplotlib:最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB,模仿MATLAB构建

官网:https://matplotlib.org/

绘制折线图

matplotlib基本要点

每个红色的点是坐标,把5个点的坐标连接成一条线,组成了一个折线图。那么到底如何把它通过代码画出来呢?

在使用绘图的时候应该还要考虑下面的要点:

1.设置图片大小(想要一个高清无码大图)
2.保存到本地
3.描述信息,比如x轴和y轴表示什么,这个图表示什么
4.调整x或者y的刻度的间距
5.线条的样式(比如颜色,透明度等)
6.标记出特殊的点(比如告诉别人最高点和最低点在哪里)
7.给图片添加一个水印(防伪,防止盗用)

通过下面的小例子来看一下matplotlib简单的使用,假设一天中每隔两个小时(range(2,26,2))的气温(℃)分别是
[15,13,14.5,17,20,25,26,26,27,22,18,15]

from matplotlib import pyplot as plt# x,y轴,2个都是可迭代对象
x = range(2,26,2)
y = [15,13,14.5,17,20,25,26,26,27,22,18,15]# 设置图片大小,figsize传入的是宽,高,元组对象;dpi:图的分辨率(每英寸点数)
plt.figure(figsize=(16,8),dpi=80)# 设置x轴的刻度xticks,y轴yticks
_xtick_labels = [i/2 for i in range(4,49)]
# plt.xticks(x[::3]) # 当刻度太密集时候使用列表的步长(间隔取值)来解决,matplotlib会自动帮我们对应
# plt.xticks(_xtick_labels)
plt.xticks(range(25,50))
# plt.xticks(_xtick_labels)
plt.yticks(range(min(y),max(y)+1))# 绘制折线图plot
plt.plot(x,y)# 保存图片,可以保存为svg这种矢量图格式,放大不会有锯齿
plt.savefig('./t1.png')  # 运行程序后展示图形
plt.show()

再看例子:

如果下面的列表a表示10点到12点的每一分钟的气温,如何绘制折线图观察每分钟气温的变化情况?

a= [random.randint(20,35) for i in range(120)]

from matplotlib import pyplot as plt
import random
from matplotlib import font_manager, rc# windows更改字体的方式一:这种方式是全局的,只在该处配置了即可,后面的都不用了
# font = {'family': 'Microsoft Yahei',
#         'size': '10'}
# rc("font", **font)
# 方式二:设置中文字体,找到该字体的路径,然后在需要使用中文的地方使用fontproperties参数即可
my_font = font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')
# plt.xticks(list(x)[::3],_xtick_labels[::3],rotation=45,fontproperties=my_font)x = range(0, 120)
y = [random.randint(18, 35) for i in range(120)]
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(x, y)# 调整x轴的刻度
_xtick_labels = ['10点{}分'.format(i) for i in range(60)]
_xtick_labels += ['11点{}分'.format(i) for i in range(60)]
# 取步长,数字和字符串一一对应,数据的长度一样。rotaion = 45 顺时针旋转45度,fontproperties使用中文字体。
plt.xticks(list(x)[::3], _xtick_labels[::3], rotation=45, fontproperties=my_font)# 图像添加描述信息
plt.xlabel('时间', fontproperties=my_font)  # 设置x轴的描述
plt.ylabel('温度 单位(℃)', fontproperties=my_font) # 设置y轴的描述
plt.title('10点到12点每分钟的气温变化情况', fontproperties=my_font) # 设置标题plt.show()

现在有一个题:

假设大家在30岁的时候,根据自己的实际情况,统计出来了从11岁到30岁每年交的女(男)朋友的数量如列表a,请绘制出该数据的折线图,以便分析自己每年交女(男)朋友的数量走势

a = [1,0,1,1,2,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1]

要求:

y轴表示个数,x轴表示岁数,比如11岁,12岁等

from matplotlib import pyplot as plt
from matplotlib import font_managermy_font = font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')y = [1, 0, 1, 1, 2, 4, 3, 2, 3, 4, 4, 5, 6, 5, 4, 3, 3, 1, 1, 1]
x = range(11, 31)plt.figure(figsize=(20, 8), dpi=80)_xtick_labels = ['{}岁'.format(i) for i in x]
plt.xticks(x, _xtick_labels, fontproperties=my_font)
plt.yticks(range(0, 9))plt.xlabel('年龄',fontproperties=my_font)
plt.ylabel('人数',fontproperties=my_font)
plt.title('不同年龄段交的异性朋友人数',fontproperties=my_font)# 绘制网格
plt.grid(alpha=0.3)plt.plot(x, y)
plt.show()

自定义绘制图形的风格

为每条线添加图例

升级一下上面的这个题:

假设大家在30岁的时候,根据自己的实际情况,统计出来了你和你同桌各自从11岁到30岁每年交的女(男)朋友的数量如列表a和b,请在一个图中绘制出该数据的折线图,以便比较自己和同桌20年间的差异,同时分析每年交女(男)朋友的数量走势

a = [1,0,1,1,2,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1]

b = [1,0,3,1,2,2,3,3,2,1 ,2,1,1,1,1,1,1,1,1,1]

要求:

y轴表示个数,x轴表示岁数,比如11岁,12岁等

from matplotlib import pyplot as plt
from matplotlib import font_managermy_font = font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')y_1 = [1, 0, 1, 1, 2, 4, 3, 2, 3, 4, 4, 5, 6, 5, 4, 3, 3, 1, 1, 1]
y_2 = [1, 0, 3, 1, 2, 2, 3, 3, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1]x = range(11, 31)plt.figure(figsize=(20, 8), dpi=80)_xtick_labels = ['{}岁'.format(i) for i in x]
plt.xticks(x, _xtick_labels, fontproperties=my_font)
# plt.yticks(range(0, 9))plt.xlabel('年龄', fontproperties=my_font)
plt.ylabel('人数', fontproperties=my_font)
plt.title('不同年龄段交的异性朋友人数', fontproperties=my_font)# 绘制网格
plt.grid(alpha=0.3, linestyle=':')# 添加图例,这里legend使用中文的属性是prop,其他的都是fontproperties
plt.plot(x, y_1, label='你自己', color='#006e54')
plt.plot(x, y_2, label='你同桌', color='#bf242a', linestyle='--')
plt.legend(prop=my_font, loc='upper left')plt.show()

Matplotlib水印

import matplotlib.pyplot as plt
import numpy as npx = np.linspace(0.0,10,40)
y = np.random.randn(40)plt.figure(figsize=(20,8),dpi=80)plt.plot(x,                 # X轴数据y,                 # Y轴数据ls="-",            # 线条样式lw=2,              # 线条宽度marker="o",        # x轴Y轴对应数据点的样式ms=20,             # 数据点的大小mfc="orange",      # 数据点填充颜色alpha=0.6)         # 数据点的透明度
plt.grid(ls=":",            # 网格样式(虚线)color="gray",      # 网格颜色alpha=0.5)         # 网格透明度
plt.text(x=1,               # 水印开头左下角对应的X点y=2,               # 水印开头左下角对应的Y点s="Matplotlib",    # 水印文本fontsize=50,       # 水印大小color="gray",      # 水印颜色alpha=0.5)         # 水印是通过透明度控制的
plt.show()

Matplotlib添加注释

matplotlib.pyplot.annotate

**小结:**上面我们都干了什么

1.绘制了折线图(plt.plot)

2.设置了图片的大小和分辨率(plt.figure)

3.实现了图片的保存(plt.savefig)

4.设置了xy轴上的刻度和字符串解决了刻度稀疏和密集的问题(xticks)

5.设置了标题,x,y轴的lable(title,xlable,ylable)

6.设置了字体(font_manager. fontProperties,matplotlib.rc)

7.在一个图上绘制多个图形(plt多次plot即可)

8.为不同的图形添加图例,绘制网格(plt.legend,plt.grid)

9.添加水印和注释

绘制散点图

matplotlib能够绘制折线图,散点图,柱状图,直方图,箱线图,饼图等,但是,我们需要知道不同的统计图到底能够表示出什么,以此来决定选择哪种统计图来更直观的呈现我们的数据

对比常用统计图

折线图:以折线的上升或下降来表示统计数量的增减变化的统计图
特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)

直方图:由一系列高度不等的纵向条纹或线段表示数据分布的情况。一般用横轴表示数据范围,纵轴表示分布情况。
特点:绘制连续性的数据,展示一组或者多组数据的分布状况(统计)

条形图:排列在工作表的列或行中的数据可以绘制到条形图中。
特点:绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计)

散点图:用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。
特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)

折线图的更多应用场景

  • 呈现公司产品(不同区域)每天活跃用户数
  • 呈现app每天下载数量
  • 呈现产品新功能上线后,用户点击次数随时间的变化
  • 呈现员工每天上下班时间

散点图

假设北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温和随时间(天)变化的某种规律?

a = [11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23]

b = [26,26,28,19,21,17,16,19,18,20,20,19,22,23,17,20,21,20,22,15,11,15,5,13,17,10,11,13,12,13,6]

import matplotlib.pyplot as plt
from matplotlib import font_manager# 字体设置
my_font = font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')
# x,y轴规划
y_3 = [11, 17, 16, 11, 12, 11, 12, 6, 6, 7, 8, 9, 12, 15, 14, 17, 18, 21, 16, 17, 20, 14, 15, 15, 15, 19, 21, 22, 22,22, 23]
y_10 = [26, 26, 28, 19, 21, 17, 16, 19, 18, 20, 20, 19, 22, 23, 17, 20, 21, 20, 22, 15, 11, 15, 5, 13, 17, 10, 11, 13,12, 13, 6]x_3 = range(1, 32)
x_10 = range(51, 82)# 设置图片大小
plt.figure(figsize=(20, 8), dpi=80)# label是添加图例的内容,scatter是绘制散点图的方法
plt.scatter(x_3, y_3, label='3月份')
plt.scatter(x_10, y_10, label='10月份')# 添加图例
plt.legend(prop=my_font, loc='upper left')# 添加描述
plt.xlabel('时间', fontproperties=my_font)
plt.ylabel('温度(℃)', fontproperties=my_font)
plt.title('气温随时间的变化', fontproperties=my_font)# 调整x轴的刻度,数字和字符串一一对应
_x = list(x_3) + list(x_10)
_xtick_labels = ['3月{}日'.format(i) for i in x_3]
_xtick_labels += ['10月{}日'.format(i - 50) for i in x_10]
plt.xticks(_x[::3], _xtick_labels[::3], fontproperties=my_font, rotation=45)plt.show()

散点图的更多应用场景:

  • 不同条件(维度)之间的内在关联关系
  • 观察数据的离散聚合程度

绘制条形图

假设你获取到了2017年内地电影票房前20的电影(列表a)和电影票房数据(列表b),那么如何更加直观的展示该数据?

a = [“战狼2”,“速度与激情8”,“功夫瑜伽”,“西游伏妖篇”,“变形金刚5:最后的骑士”,“摔跤吧!爸爸”,“加勒比海盗5:死无对证”,“金刚:骷髅岛”,“极限特工:终极回归”,“生化危机6:终章”,“乘风破浪”,“神偷奶爸3”,“智取威虎山”,“大闹天竺”,“金刚狼3:殊死一战”,“蜘蛛侠:英雄归来”,“悟空传”,“银河护卫队2”,“情圣”,“新木乃伊”,]

b=[56.01,26.94,17.53,16.49,15.45,12.96,11.8,11.61,11.28,11.12,10.49,10.3,8.75,7.55,7.32,6.99,6.88,6.86,6.58,6.23] 单位:亿

说明:

import matplotlib.pyplot as plt
import matplotlib.font_managermy_font = matplotlib.font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')a = ["战狼2","速度与激情8","功夫瑜伽","西游伏妖篇","变形金刚5:最后的骑士","摔跤吧!爸爸","加勒比海盗5:死无对证","金刚:骷髅岛","极限特工:终极回归","生化危机6:终章","乘风破浪","神偷奶爸3","智取威虎山","大闹天竺","金刚狼3:殊死一战","蜘蛛侠:英雄归来","悟空传","银河护卫队2","情圣","新木乃伊",]b=[56.01,26.94,17.53,16.49,15.45,12.96,11.8,11.61,11.28,11.12,10.49,10.3,8.75,7.55,7.32,6.99,6.88,6.86,6.58,6.23]plt.figure(figsize=(20,15),dpi=80)# 绘制纵向条形图
plt.bar(range(len(a)),b,width=0.3)# 设置字符串到x轴
plt.xticks(range(len(a)),a,fontproperties=my_font,rotation=90)plt.show()

很显然这里x轴的文字有问题,长度过长,所以下面使用横向的条形图

import matplotlib.pyplot as plt
import matplotlib.font_managermy_font = matplotlib.font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')a = ["战狼2","速度与激情8","功夫瑜伽","西游伏妖篇","变形金刚5:最后的骑士","摔跤吧!爸爸","加勒比海盗5:死无对证","金刚:骷髅岛","极限特工:终极回归","生化危机6:终章","乘风破浪","神偷奶爸3","智取威虎山","大闹天竺","金刚狼3:殊死一战","蜘蛛侠:英雄归来","悟空传","银河护卫队2","情圣","新木乃伊",]b=[56.01,26.94,17.53,16.49,15.45,12.96,11.8,11.61,11.28,11.12,10.49,10.3,8.75,7.55,7.32,6.99,6.88,6.86,6.58,6.23]plt.figure(figsize=(20,15),dpi=80)# 绘制横向条形图
plt.barh(range(len(a)),b,height=0.3,color='red')# 设置字符串到y轴
plt.yticks(range(len(a)),a,fontproperties=my_font)# 设置x轴的刻度
plt.xticks(range(0,61,3))plt.grid(alpha=0.5)
plt.show()

对比题:

假设你知道了列表a中电影分别在2017-09-14(b_14), 2017-09-15(b_15), 2017-09-16(b_16)三天的票房,为了展示列表中电影本身的票房以及同其他电影的数据对比情况,应该如何更加直观的呈现该数据?

a = [“猩球崛起3:终极之战”,“敦刻尔克”,“蜘蛛侠:英雄归来”,“战狼2”]

b_16 = [15746,312,4497,319]
b_15 = [12357,156,2045,168]
b_14 = [2358,399,2358,362]

from matplotlib import pyplot as plt
from matplotlib import font_managermy_font = font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')a = ["猩球崛起3:终极之战", "敦刻尔克", "蜘蛛侠:英雄归来", "战狼2"]
b_16 = [15746, 312, 4497, 319]
b_15 = [12357, 156, 2045, 168]
b_14 = [2358, 399, 2358, 362]# 设置条形图宽度
bar_width = 0.2# x轴位置
x_14 = list(range(len(a)))
x_15 = [i + bar_width for i in x_14]
x_16 = [i + bar_width * 2 for i in x_14]plt.figure(figsize=(20, 8), dpi=80)plt.bar(range(len(a)), b_14, width=bar_width, label='9月14日')
plt.bar(x_15, b_15, width=bar_width, label='9月15日')
plt.bar(x_16, b_16, width=bar_width, label='9月16日')# 图例
plt.legend(prop=my_font)
# 调整x轴刻度,汉字居中
plt.xticks(x_15, a, fontproperties=my_font)
plt.show()

条形图的更多应用场景: 数量统计;频率统计(市场饱和度)

绘制直方图

假设你获取了250部电影的时长(列表a中),希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据?

a=[131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]

from matplotlib import pyplot as plt
from matplotlib import font_managermy_font = font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')a = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124,101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111, 78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130, 126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136, 123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127, 105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114, 105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134, 156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102, 123, 107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133, 112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135, 115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154, 136, 100, 118, 119, 133, 134,
106, 129, 126, 110, 111, 109, 141, 120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126, 114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92, 121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113, 134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110, 105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101, 131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111, 111, 133, 150]# 计算数组
d = 3  # 组距
num_bins = (max(a) - min(a)) // dplt.figure(figsize=(20, 8), dpi=80)
plt.grid(alpha=0.4)
# density显示频率分布直方图,默认频数直方图。以前是normed
plt.hist(a, num_bins, density=True)plt.xticks(range(min(a), max(a) + d, d))plt.xlabel('视频时长',fontproperties=my_font)
plt.ylabel('视频个数',fontproperties=my_font)
plt.title('视频时长对应的视频个数',fontproperties=my_font)plt.show()

现在有一个问题:

在美国2004年人口普查发现有124 million的人在离家相对较远的地方工作。根据他们从家到上班地点所需要的时间,通过抽样统计(最后一列)出了下表的数据,这些数据能够绘制成直方图么?

interval = [0,5,10,15,20,25,30,35,40,45,60,90]
width = [5,5,5,5,5,5,5,5,5,15,30,60]
quantity = [836,2737,3723,3926,3596,1438,3273,642,824,613,215,47]

前面的问题问的是什么呢?

问的是: 哪些数据能够绘制直方图。前面的问题中给出的数据都是统计之后的数据,所以为了达到直方图的效果,需要绘制条形图。所以:一般来说能够使用plt.hist方法的的是那些没有统计过的数据

from matplotlib import pyplot as plt
from matplotlib import font_managermy_font = font_manager.FontProperties(fname=r'C:\Windows\Fonts\msyh.ttc')interval = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 60, 90]
width = [5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 30, 60]
quantity = [836, 2737, 3723, 3926, 3596, 1438, 3273, 642, 824, 613, 215, 47]plt.figure(figsize=(20, 8), dpi=80)
plt.grid(alpha=0.4)# width=1条形图之间没有间隙
plt.bar(range(12), quantity, width=1)# 设置x轴的刻度
_x = [i - 0.5 for i in range(13)]
_xtick_labels = interval + [150]
plt.xticks(_x, _xtick_labels)plt.show()

matplotlib常见问题总结

1.应该选择那种图形来呈现数据
2.matplotlib.plot(x,y)
3.matplotlib.bar(x,y)
4.matplotlib.scatter(x,y)
5.matplotlib.hist(data,bins,normed)
6.xticks和yticks的设置
7.label和titile,grid的设置
8.绘图的大小和保存图片

matplotlib使用的流程总结

1.明确问题
2.选择图形的呈现方式
3.准备数据
4.绘图和图形完善

更多的绘图工具

plotly: 可视化工具中的github,相比于matplotlib更加简单,图形更加漂亮,同时兼容matplotlib和pandas

plotly官网:https://plotly.com/python/

使用用法: 简单,照着文档写即可

二、numpy

什么是numpy:

是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。是Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算

numpy应用:

NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用, 这种组合广泛用于替代 MatLab,是一个强大的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。

SciPy 是一个开源的 Python 算法库和数学工具包。SciPy 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。

Matplotlib 是 Python 编程语言及其数值数学扩展包 NumPy 的可视化操作界面。它为利用通用的图形用户界面工具包,如 Tkinter, wxPython, Qt 或 GTK+ 向应用程序嵌入式绘图提供了应用程序接口(API)。

Ndarray 对象

NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。

ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。

ndarray 内部由以下内容组成:

  • 一个指向数据(内存或内存映射文件中的一块数据)的指针。
  • 数据类型或 dtype,描述在数组中的固定大小值的格子。
  • 一个表示数组形状(shape)的元组,表示各维度大小的元组。
  • 一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。

ndarray 的内部结构:

跨度可以是负数,这样会使数组在内存中后向移动,切片中 obj[::-1]obj[:,::-1] 就是如此。

创建一个 ndarray 只需调用 NumPy 的 array 函数即可:

numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

参数说明:

名称 描述
object 数组或嵌套的数列
dtype 数组元素的数据类型,可选
copy 对象是否需要复制,可选
order 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok 默认返回一个与基类类型一致的数组
ndmin 指定生成数组的最小维度

实例:

import numpy as np
a = np.array([1,2,3])
print (a)  # [1, 2, 3]# 多于一个维度
a = np.array([[1,  2],  [3,  4]])
print (a)
[[1, 2] [3, 4]]# 最小维度
a = np.array([1,  2,  3,4,5], ndmin =  2)
print (a) # [[1, 2, 3, 4, 5]]# dtype 参数
a = np.array([1,  2,  3], dtype = complex)
print (a)  # [ 1.+0.j,  2.+0.j,  3.+0.j]

数据类型

常用 NumPy 基本类型

名称 描述
bool_ 布尔型数据类型(True 或者 False)
int_ 默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc 与 C 的 int 类型一样,一般是 int32 或 int 64
intp 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8 字节(-128 to 127)
int16 整数(-32768 to 32767)
int32 整数(-2147483648 to 2147483647)
int64 整数(-9223372036854775808 to 9223372036854775807)
uint8 无符号整数(0 to 255)
uint16 无符号整数(0 to 65535)
uint32 无符号整数(0 to 4294967295)
uint64 无符号整数(0 to 18446744073709551615)
float_ float64 类型的简写
float16 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_ complex128 类型的简写,即 128 位复数
complex64 复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128 复数,表示双 64 位浮点数(实数部分和虚数部分)

numpy 的数值类型实际上是 dtype 对象的实例,并对应唯一的字符,包括 np.bool_,np.int32,np.float32,等等。

数据类型对象 (dtype)

数据类型对象(numpy.dtype 类的实例)用来描述与数组对应的内存区域是如何使用,它描述了数据的以下几个方面:

  • 数据的类型(整数,浮点数或者 Python 对象)
  • 数据的大小(例如, 整数使用多少个字节存储)
  • 数据的字节顺序(小端法或大端法)
  • 在结构化类型的情况下,字段的名称、每个字段的数据类型和每个字段所取的内存块的部分
  • 如果数据类型是子数组,那么它的形状和数据类型是什么。

字节顺序是通过对数据类型预先设定 <> 来决定的。 < 意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。> 意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。

dtype 对象是使用以下语法构造的:

numpy.dtype(object, align, copy)
  • object - 要转换为的数据类型对象
  • align - 如果为 true,填充字段使其类似 C 的结构体。
  • copy - 复制 dtype 对象 ,如果为 false,则是对内置数据类型对象的引用

实例

import numpy as np
# 使用标量类型
dt = np.dtype(np.int32)
print(dt) # int32# int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替
dt = np.dtype('i4')
print(dt)  # int32# 字节顺序标注
dt = np.dtype('<i4')
print(dt) # int32# 下面实例展示结构化数据类型的使用,类型字段和对应的实际类型将被创建
# 首先创建结构化数据类型
dt = np.dtype([('age',np.int8)])
print(dt) # [('age', 'i1')]# 将数据类型应用于 ndarray 对象
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a) # [(10,) (20,) (30,)]# 类型字段名可以用于存取实际的 age 列
print(a['age'])  # [10 20 30]# 下面的示例定义一个结构化数据类型 student,包含字符串字段 name,整数字段 age,及浮点字段 marks,并将这个 dtype 应用到 ndarray 对象。
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
print(student) # [('name', 'S20'), ('age', 'i1'), ('marks', 'f4')]
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print(a) # [(b'abc', 21, 50.) (b'xyz', 18, 75.)]

每个内建类型都有一个唯一定义它的字符代码,如下

字符 对应类型
b 布尔型
i (有符号) 整型
u 无符号整型 integer
f 浮点型
c 复数浮点型
m timedelta(时间间隔)
M datetime(日期时间)
O (Python) 对象
S, a (byte-)字符串
U Unicode
V 原始数据 (void)

数组属性

NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。

NumPy 的数组中比较重要 ndarray 对象属性有:

属性 说明
ndarray.ndim 秩,即轴的数量或维度的数量
ndarray.shape 数组的维度,对于矩阵,n 行 m 列
ndarray.size 数组元素的总个数,相当于 .shape 中 n*m 的值
ndarray.dtype ndarray 对象的元素类型
ndarray.itemsize ndarray 对象中每个元素的大小,以字节为单位

实例

# ndarray.ndim 用于返回数组的维数,等于秩。
import numpy as np a = np.arange(24)    # arange就相当于Python中的range
print (a.ndim)             # a 现只有一个维度
# 现在调整其大小
b = a.reshape(2,4,3)  # b 现在拥有三个维度
print (b.ndim)# ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。比如,一个二维数组,其维度表示"行数"和"列数"。ndarray.shape 也可以用于调整数组大小。
a = np.array([[1,2,3],[4,5,6]])
print (a.shape)  # (2, 3)
a.shape =  (3,2)
print (a)
[[1 2][3 4][5 6]]# NumPy 也提供了 reshape 函数来调整数组大小。ndarray.reshape 通常返回的是非拷贝副本,即改变返回后数组的元素,原数组对应元素的值也会改变。
a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2)
print (b)
[[1, 2] [3, 4] [5, 6]]#ndarray.itemsize 以字节的形式返回数组中每一个元素的大小。
#例如,一个元素类型为 float64 的数组 itemsize 属性值为 8(float64 占用 64 个 bits,每个字节长度为 8,所以 64/8,占用 8 个字节),又如,一个元素类型为 complex32 的数组 item 属性为 4(32/8)。# 数组的 dtype 为 int8(一个字节)
x = np.array([1,2,3,4,5], dtype = np.int8)
print (x.itemsize)
# 数组的 dtype 现在为 float64(八个字节)
y = np.array([1,2,3,4,5], dtype = np.float64)
print (y.itemsize)

创建数组

ndarray 数组除了可以使用底层 ndarray 构造器来创建外,也可以通过以下几种方式来创建。

numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:

numpy.empty(shape, dtype = float, order = 'C')

numpy.zeros创建指定大小的数组,数组元素以 0 来填充:

numpy.zeros(shape, dtype = float, order = 'C')

numpy.ones创建指定形状的数组,数组元素以 1 来填充:

numpy.ones(shape, dtype = None, order = 'C')

参数说明:

参数 描述
shape 数组形状
dtype 数据类型,可选
order ‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组

实例

# 创建空数组的实例:
import numpy as np
x = np.empty([3,2], dtype = int)
print (x)
# 输出结果为:
[[ 6917529027641081856  5764616291768666155][ 6917529027641081859 -5764598754299804209][          4497473538      844429428932120]]
# 注意 − 数组元素为随机值,因为它们未初始化。# 默认为浮点数
x = np.zeros(5)
print(x)
# 设置类型为整数
y = np.zeros((5,), dtype = np.int)
print(y)
# 自定义类型
z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])
print(z)
[0. 0. 0. 0. 0.]
[0 0 0 0 0]
[[(0, 0) (0, 0)][(0, 0) (0, 0)]]# 默认为浮点数
x = np.ones(5)
print(x)
# 自定义类型
x = np.ones([2,2], dtype = int)
print(x)
[1. 1. 1. 1. 1.]
[[1 1][1 1]]

从已有的数组创建数组

numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。

numpy.asarray(a, dtype = None, order = None)
参数 描述
a 任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组
dtype 数据类型,可选
order 可选,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。

实例

# 将列表转换为 ndarray:
import numpy as np x =  [1,2,3]
a = np.asarray(x)
print (a) # [1  2  3]# 将元组转换为 ndarray:
x =  (1,2,3)
a = np.asarray(x)
print (a) # [1  2  3]# 将元组列表转换为 ndarray:
x =  [(1,2,3),(4,5)]
a = np.asarray(x)
print (a)  # [(1, 2, 3) (4, 5)]# 设置了 dtype 参数:
x =  [1,2,3]
a = np.asarray(x, dtype =  float)
print (a)  # [ 1.  2.  3.]

numpy.frombuffer 用于实现动态数组。

numpy.frombuffer 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。

numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)

**注意:**buffer 是字符串的时候,Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。

参数 描述
buffer 可以是任意对象,会以流的形式读入。
dtype 返回数组的数据类型,可选
count 读取的数据数量,默认为-1,读取所有数据。
offset 读取的起始位置,默认为0。
s =  b'Hello World'
a = np.frombuffer(s, dtype =  'S1')
print (a) # [b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd']

numpy.fromiter 方法从可迭代对象中建立 ndarray 对象,返回一维数组。

numpy.fromiter(iterable, dtype, count=-1)
参数 描述
iterable 可迭代对象
dtype 返回数组的数据类型
count 读取的数据数量,默认为-1,读取所有数据
# 使用 range 函数创建列表对象
list=range(5)
it=iter(list)# 使用迭代器创建 ndarray
x=np.fromiter(it, dtype=float)
print(x) # [0. 1. 2. 3. 4.]

从数值范围创建数组

numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,函数格式如下:

numpy.arange(start, stop, step, dtype)

根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。

参数 描述
start 起始值,默认为0
stop 终止值(不包含)
step 步长,默认为1
dtype 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。

实例

# 生成 0 到 5 的数组:
import numpy as npx = np.arange(5)
print (x)   # [0  1  2  3  4]# 设置了 dtype
x = np.arange(5, dtype =  float)
print (x) # [0.  1.  2.  3.  4.]# 设置了起始值、终止值及步长:
x = np.arange(10,20,2)
print (x)  # [10  12  14  16  18]

numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下:

np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数 描述
start 序列的起始值
stop 序列的终止值,如果endpointtrue,该值包含于数列中
num 要生成的等步长的样本数量,默认为50
endpoint 该值为 true 时,数列中包含stop值,反之不包含,默认是True。
retstep 如果为 True 时,生成的数组中会显示间距,反之不显示。
dtype ndarray 的数据类型

实例

a = np.linspace(1,1,10)
print(a)  #[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]# 将 endpoint 设为 false,不包含终止值,如果将 endpoint 设为 true,则会包含 20。:
a = np.linspace(10, 20,  5, endpoint =  False)
print(a)  # [10. 12. 14. 16. 18.]# 设置间距
a =np.linspace(1,10,10,retstep= True)print(a)
# 拓展例子
b =np.linspace(1,10,10).reshape([10,1])
print(b)(array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.]), 1.0)
[[ 1.][ 2.][ 3.][ 4.][ 5.][ 6.][ 7.][ 8.][ 9.][10.]]

numpy.logspace 函数用于创建一个于等比数列。格式如下:

np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
参数 描述
start 序列的起始值为:base ** start
stop 序列的终止值为:base ** stop。如果endpointtrue,该值包含于数列中
num 要生成的等步长的样本数量,默认为50
endpoint 该值为 true 时,数列中中包含stop值,反之不包含,默认是True。
base 对数 log 的底数。
dtype ndarray 的数据类型
# 默认底数是 10
a = np.logspace(1.0,  2.0, num =  10)
print (a)
[ 10.           12.91549665     16.68100537      21.5443469  27.82559402      35.93813664   46.41588834     59.94842503      77.42636827    100.    ]# 将对数的底数设置为 2 :
a = np.logspace(0,9,10,base=2)
print (a)
[  1.   2.   4.   8.  16.  32.  64. 128. 256. 512.]

切片和索引

ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。

ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。

实例

import numpy as npa = np.arange(10)
s = slice(2,7,2)   # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s])  # [2  4  6]以上实例中,我们首先通过 arange() 函数创建 ndarray 对象。 然后,分别设置起始,终止和步长的参数为 2,7 和 2。我们也可以通过冒号分隔切片参数 start:stop:step 来进行切片操作:
b = a[2:7:2]   # 从索引 2 开始到索引 7 停止,间隔为 2
print(b)  # [2  4  6]冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。a = np.arange(10)  # [0 1 2 3 4 5 6 7 8 9]
b = a[5]
print(b)  # 5
print(a[2:]) # [2  3  4  5  6  7  8  9]
print(a[2:5]) # [2  3  4]多维数组同样适用上述索引提取方法:
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# 从某个索引处开始切割
print('从数组索引 a[1:] 处开始切割')
print(a[1:])
[[1 2 3][3 4 5][4 5 6]]
从数组索引 a[1:] 处开始切割
[[3 4 5][4 5 6]]切片还可以包括省略号 …,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的 ndarray。
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print (a[...,1])   # 第2列元素[2 4 5]
print (a[1,...])   # 第2行元素 [3 4 5]
print (a[...,1:])  # 第2列及剩下的所有元素[[2 3][4 5][5 6]]

整数数组索引

# 获取数组中(0,0),(1,1)和(2,0)位置处的元素。
import numpy as np x = np.array([[1,  2],  [3,  4],  [5,  6]])
y = x[[0,1,2],  [0,1,0]]
print (y)  # [1  4  5]# 获取了 4X3 数组中的四个角的元素。 行索引是 [0,0] 和 [3,3],而列索引是 [0,2] 和 [0,2]。
x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])
print ('我们的数组是:' )
print (x)
print ('\n')
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
print  ('这个数组的四个角元素是:')
print (y)我们的数组是:
[[ 0  1  2][ 3  4  5][ 6  7  8][ 9 10 11]]这个数组的四个角元素是:
[[ 0  2][ 9 11]]#返回的结果是包含每个角元素的 ndarray 对象。可以借助切片 : 或 … 与索引数组组合。如下面例子:
a = np.array([[1,2,3], [4,5,6],[7,8,9]])
b = a[1:3, 1:3]
c = a[1:3,[1,2]]
d = a[...,1:]
print(b)
print(c)
print(d)[[5 6][8 9]]
[[5 6][8 9]]
[[2 3][5 6][8 9]]

布尔索引

可以通过一个布尔数组来索引目标数组。布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。

# 获取大于 5 的元素:
import numpy as np x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])
print ('我们的数组是:')
print (x)
print ('\n')
# 现在我们会打印出大于 5 的元素
print  ('大于 5 的元素是:')
print (x[x >  5])我们的数组是:
[[ 0  1  2][ 3  4  5][ 6  7  8][ 9 10 11]]大于 5 的元素是:
[ 6  7  8  9 10 11]# 使用了 ~(取补运算符)来过滤 NaN
a = np.array([np.nan,  1,2,np.nan,3,4,5])
print (a[~np.isnan(a)])   # [ 1.   2.   3.   4.   5.]# 从数组中过滤掉非复数元素
a = np.array([1,  2+6j,  5,  3.5+5j])
print (a[np.iscomplex(a)]) # [2.0+6.j  3.5+5.j]

花式索引

花式索引指的是利用整数数组进行索引。

花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。

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

# 传入顺序索引数组
import numpy as np x=np.arange(32).reshape((8,4))
print (x[[4,2,1,7]])
[[16 17 18 19][ 8  9 10 11][ 4  5  6  7][28 29 30 31]]# 传入倒序索引数组
print (x[[-4,-2,-1,-7]])
[[16 17 18 19][24 25 26 27][28 29 30 31][ 4  5  6  7]]# 传入多个索引数组(要使用np.ix_)
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
[[ 4  7  5  6][20 23 21 22][28 31 29 30][ 8 11  9 10]]
# np.ix_([1,5,7,2],[0,3,1,2])]这句话会输出一个4*4的矩阵,其中的元素分别是:
x[1,0] x[1,3] x[1,1] x[1,2]
x[5,0] x[5,3] x[5,1] x[5,2]
x[7,0] x[7,3] x[7,1] x[7,2]
x[2,0] x[2,3] x[2,1] x[2,2]
# 相当于:
y=np.array([[x[1,0], x[1,3], x[1,1], x[1,2]],\[x[5,0], x[5,3], x[5,1],x[5,2]],\[x[7,0] ,x[7,3], x[7,1], x[7,2]],\[x[2,0], x[2,3], x[2,1], x[2,2]]])
#就是说,如果 np.xi_ 中输入两个列表,则第一个列表存的是待提取元素的行标,第二个列表存的是待提取元素的列标,第一个列表中的每个元素都会对应的第二个列表中的每个值构成一个数组索引,构成新矩阵的一行元素。

广播(Broadcast)

广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。

实例

import numpy as np a = np.array([1,2,3,4])
b = np.array([10,20,30,40])
c = a * b
print (c)  # [ 10  40  90 160]# 当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。
a = np.array([[ 0, 0, 0],[10,10,10],[20,20,20],[30,30,30]])
b = np.array([1,2,3])
print(a + b)
[[ 1  2  3][11 12 13][21 22 23][31 32 33]]# 4x3 的二维数组与长为 3 的一维数组相加,等效于把数组 b 在二维上重复 4 次再运算
a = np.array([[ 0, 0, 0],[10,10,10],[20,20,20],[30,30,30]])
b = np.array([1,2,3])
bb = np.tile(b, (4, 1))  # 重复 b 的各个维度,tile() 函数,就是将原矩阵横向、纵向地复制。这里是将行复制为原来的四倍
print(a + bb)
[[ 1  2  3][11 12 13][21 22 23][31 32 33]]

迭代数组

NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。

迭代器最基本的任务的可以完成对数组元素的访问。

实例

# 使用 arange() 函数创建一个 2X3 数组,并使用 nditer 对它进行迭代。
import numpy as npa = np.arange(6).reshape(2,3)
print ('原始数组是:')
print (a)
print ('\n')
print ('迭代输出元素:')
for x in np.nditer(a):print (x, end=", " )
print ('\n')
'''
原始数组是:
[[0 1 2][3 4 5]]迭代输出元素:
0, 1, 2, 3, 4, 5,
'''#以上实例不是使用标准 C 或者 Fortran 顺序,选择的顺序是和数组内存布局一致的,这样做是为了提升访问的效率,默认是行序优先(row-major order,或者说是 C-order)。这反映了默认情况下只需访问每个元素,而无需考虑其特定顺序。我们可以通过迭代上述数组的转置来看到这一点,并与以 C 顺序访问数组转置的 copy 方式做对比,如下实例:
for x in np.nditer(a.T):   # a.T a的装置矩阵print (x, end=", " )
print ('\n')for x in np.nditer(a.T.copy(order='C')):print (x, end=", " )
print ('\n')
'''
0, 1, 2, 3, 4, 5, 0, 3, 1, 4, 2, 5,
'''
# 从上述例子可以看出,a 和 a.T 的遍历顺序是一样的,也就是他们在内存中的存储顺序也是一样的,但是 a.T.copy(order = 'C') 的遍历结果是不同的,那是因为它和前两种的存储方式是不一样的,默认是按行访问。

控制遍历顺序

  • for x in np.nditer(a, order='F'):Fortran order,即是列序优先;
  • for x in np.nditer(a.T, order='C'):C order,即是行序优先;

实例

import numpy as npa = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a+'\n')
print ('原始数组的转置是:')
b = a.T
print (b+'\n')
print ('以 C 风格顺序排序:')
c = b.copy(order='C')
print (c)
for x in np.nditer(c):  print (x, end=", " )
print  ('\n')
print  ('以 F 风格顺序排序:')
c = b.copy(order='F')
print (c)
for x in np.nditer(c):  print (x, end=", " )'''
原始数组是:
[[ 0  5 10 15][20 25 30 35][40 45 50 55]]原始数组的转置是:
[[ 0 20 40][ 5 25 45][10 30 50][15 35 55]]以 C 风格顺序排序:
[[ 0 20 40][ 5 25 45][10 30 50][15 35 55]]
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 以 F 风格顺序排序:
[[ 0 20 40][ 5 25 45][10 30 50][15 35 55]]
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,
'''# 可以通过显式设置,来强制 nditer 对象使用某种顺序:
for x in np.nditer(a, order =  'C'):  print (x, end=", " )
for x in np.nditer(a, order =  'F'):  print (x, end=", " )

修改数组中元素的值

nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。

import numpy as npa = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\n')
for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x
print ('修改后的数组是:')
print (a)
'''
原始数组是:
[[ 0  5 10 15][20 25 30 35][40 45 50 55]]修改后的数组是:
[[  0  10  20  30][ 40  50  60  70][ 80  90 100 110]]
'''

外部循环

nditer类的构造器拥有flags参数,它可以接受下列值:

参数 描述
c_index 可以跟踪 C 顺序的索引
f_index 可以跟踪 Fortran 顺序的索引
multi-index 每次迭代可以跟踪一种索引类型
external_loop 给出的值是具有多个值的一维数组,而不是零维数组
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\n')
print ('修改后的数组是:')
for x in np.nditer(a, flags =  ['external_loop'], order =  'F'):  print (x, end=", " )
'''
原始数组是:
[[ 0  5 10 15][20 25 30 35][40 45 50 55]]修改后的数组是:
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],
'''

广播迭代

如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。 假设数组 a 的维度为 3X4,数组 b 的维度为 1X4 ,则使用以下迭代器(数组 b 被广播到 a 的大小)。

import numpy as np a = np.arange(0,60,5)
a = a.reshape(3,4)
print  ('第一个数组为:')
print (a)
print  ('\n')
print ('第二个数组为:')
b = np.array([1,  2,  3,  4], dtype =  int)
print (b)
print ('\n')
print ('修改后的数组为:')
for x,y in np.nditer([a,b]):  print ("%d:%d"  %  (x,y), end=", " )'''
第一个数组为:
[[ 0  5 10 15][20 25 30 35][40 45 50 55]]第二个数组为:
[1 2 3 4]修改后的数组为:
0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,
'''

数组操作

  • 修改数组形状
  • 翻转数组
  • 修改数组维度
  • 连接数组
  • 分割数组
  • 数组元素的添加与删除

修改数组形状

函数 描述
reshape 不改变数据的条件下修改形状
flat 数组元素迭代器
flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
ravel 返回展开数组,修改会影响原始数组

numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下: numpy.reshape(arr, newshape, order=‘C’)

  • arr:要修改形状的数组
  • newshape:整数或者整数数组,新的形状应当兼容原有形状
  • order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。

实例

import numpy as npa = np.arange(8)
print ('原始数组:')
print (a)
print ('\n')b = a.reshape(4,2)
print ('修改后的数组:')
print (b)
'''
原始数组:
[0 1 2 3 4 5 6 7]修改后的数组:
[[0 1][2 3][4 5][6 7]]
'''# numpy.ndarray.flat 是一个数组元素迭代器
a = np.arange(9).reshape(3,3)
print ('原始数组:')
for row in a:print (row)#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
print ('迭代后的数组:')
for element in a.flat:print (element)
'''原始数组:
[0 1 2]
[3 4 5]
[6 7 8]
迭代后的数组:
0
1
2
3
4
5
6
7
8
'''# numpy.ndarray.flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
a = np.arange(8).reshape(2,4)print ('原数组:')
print (a)
print ('\n')
# 默认按行print ('展开的数组:')
print (a.flatten())
print ('\n')print ('以 F 风格顺序展开的数组:')
print (a.flatten(order = 'F'))'''
原数组:
[[0 1 2 3][4 5 6 7]]展开的数组:
[0 1 2 3 4 5 6 7]以 F 风格顺序展开的数组:
[0 4 1 5 2 6 3 7]
'''#numpy.ravel() 展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,有点类似 C/C++引用reference的意味),修改会影响原始数组。该函数接收两个参数:numpy.ravel(a, order='C')
a = np.arange(8).reshape(2,4)print ('原数组:')
print (a)
print ('\n')print ('调用 ravel 函数之后:')
print (a.ravel())
print ('\n')print ('以 F 风格顺序调用 ravel 函数之后:')
print (a.ravel(order = 'F'))'''
原数组:
[[0 1 2 3][4 5 6 7]]调用 ravel 函数之后:
[0 1 2 3 4 5 6 7]以 F 风格顺序调用 ravel 函数之后:
[0 4 1 5 2 6 3 7]
'''

翻转数组

函数 描述
transpose 对换数组的维度
ndarray.T self.transpose() 相同
rollaxis 向后滚动指定的轴
swapaxes 对换数组的两个轴

numpy.transpose 函数用于对换数组的维度,格式如下:

numpy.transpose(arr, axes)

参数说明:

  • arr:要操作的数组
  • axes:整数列表,对应维度,通常所有维度都会对换。

实例

import numpy as npa = np.arange(12).reshape(3,4)print ('原数组:')
print (a )
print ('\n')print ('对换数组:')
print (np.transpose(a))
'''
原数组:
[[ 0  1  2  3][ 4  5  6  7][ 8  9 10 11]]对换数组:
[[ 0  4  8][ 1  5  9][ 2  6 10][ 3  7 11]]
'''# numpy.ndarray.T 类似 numpy.transpose:
print (a.T)
'''
[[ 0  4  8][ 1  5  9][ 2  6 10][ 3  7 11]]
'''

numpy.rollaxis 函数向后滚动特定的轴到一个特定位置,格式如下:

numpy.rollaxis(arr, axis, start)

参数说明:

  • arr:数组
  • axis:要向后滚动的轴,其它轴的相对位置不会改变
  • start:默认为零,表示完整的滚动。会滚动到特定位置。
import numpy as np# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)print ('原数组:')
print (a)
print ('获取数组中一个值:')
print(np.where(a==6))
print(a[1,1,0])  # 为 6
print ('\n')# 将轴 2 滚动到轴 0(宽度到深度)print ('调用 rollaxis 函数:')
b = np.rollaxis(a,2,0)
print (b)
# 查看元素 a[1,1,0],即 6 的坐标,变成 [0, 1, 1]
# 最后一个 0 移动到最前面
print(np.where(b==6))
print ('\n')# 将轴 2 滚动到轴 1:(宽度到高度)print ('调用 rollaxis 函数:')
c = np.rollaxis(a,2,1)
print (c)
# 查看元素 a[1,1,0],即 6 的坐标,变成 [1, 0, 1]
# 最后的 0 和 它前面的 1 对换位置
print(np.where(c==6))
print ('\n')
'''
原数组:
[[[0 1][2 3]][[4 5][6 7]]]
获取数组中一个值:
(array([1]), array([1]), array([0]))
6调用 rollaxis 函数:
[[[0 2][4 6]][[1 3][5 7]]]
(array([0]), array([1]), array([1]))调用 rollaxis 函数:
[[[0 2][1 3]][[4 6][5 7]]]
(array([1]), array([0]), array([1]))
'''

numpy.swapaxes 函数用于交换数组的两个轴,格式如下:

numpy.swapaxes(arr, axis1, axis2)
  • arr:输入的数组
  • axis1:对应第一个轴的整数
  • axis2:对应第二个轴的整数
import numpy as np# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)print ('原数组:')
print (a)
print ('\n')
# 现在交换轴 0(深度方向)到轴 2(宽度方向)print ('调用 swapaxes 函数后的数组:')
print (np.swapaxes(a, 2, 0))
'''
原数组:
[[[0 1][2 3]][[4 5][6 7]]]调用 swapaxes 函数后的数组:
[[[0 4][2 6]][[1 5][3 7]]]
'''

修改数组维度

维度 描述
broadcast 产生模仿广播的对象
broadcast_to 将数组广播到新形状
expand_dims 扩展数组的形状
squeeze 从数组的形状中删除一维条目

numpy.broadcast 用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。

该函数使用两个数组作为输入参数,如下:

import numpy as npx = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])  # 对 y 广播 x
b = np.broadcast(x,y)
# 它拥有 iterator 属性,基于自身组件的迭代器元组print ('对 y 广播 x:')
r,c = b.iters# Python3.x 为 next(context) ,Python2.x 为 context.next()
print (next(r), next(c))
print (next(r), next(c))
print ('\n')
# shape 属性返回广播对象的形状print ('广播对象的形状:')
print (b.shape)
print ('\n')
# 手动使用 broadcast 将 x 与 y 相加
b = np.broadcast(x,y)
c = np.empty(b.shape)print ('手动使用 broadcast 将 x 与 y 相加:')
print (c.shape)
print ('\n')
c.flat = [u + v for (u,v) in b]print ('调用 flat 函数:')
print (c)
print ('\n')
# 获得了和 NumPy 内建的广播支持相同的结果print ('x 与 y 的和:')
print (x + y)'''
对 y 广播 x:
1 4
1 5广播对象的形状:
(3, 3)手动使用 broadcast 将 x 与 y 相加:
(3, 3)调用 flat 函数:
[[5. 6. 7.][6. 7. 8.][7. 8. 9.]]x 与 y 的和:
[[5 6 7][6 7 8][7 8 9]]
'''

numpy.broadcast_to 函数将数组广播到新形状。它在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。

numpy.broadcast_to(array, shape, subok)
import numpy as npa = np.arange(4).reshape(1,4)print ('原数组:')
print (a)
print ('\n')print ('调用 broadcast_to 函数之后:')
print (np.broadcast_to(a,(4,4)))
'''
原数组:
[[0 1 2 3]]调用 broadcast_to 函数之后:
[[0 1 2 3][0 1 2 3][0 1 2 3][0 1 2 3]]
'''

numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状,函数格式如下:

 numpy.expand_dims(arr, axis)
  • arr:输入数组
  • axis:新轴插入的位置
import numpy as npx = np.array(([1,2],[3,4]))print ('数组 x:')
print (x)
print ('\n')
y = np.expand_dims(x, axis = 0)print ('数组 y:')
print (y)
print ('\n')print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
print ('\n')
# 在位置 1 插入轴
y = np.expand_dims(x, axis = 1)print ('在位置 1 插入轴之后的数组 y:')
print (y)
print ('\n')print ('x.ndim 和 y.ndim:')
print (x.ndim,y.ndim)
print ('\n')print ('x.shape 和 y.shape:')
print (x.shape, y.shape)
'''
数组 x:
[[1 2][3 4]]数组 y:
[[[1 2][3 4]]]数组 x 和 y 的形状:
(2, 2) (1, 2, 2)在位置 1 插入轴之后的数组 y:
[[[1 2]][[3 4]]]x.ndim 和 y.ndim:
2 3x.shape 和 y.shape:
(2, 2) (2, 1, 2)
'''

numpy.squeeze 函数从给定数组的形状中删除一维的条目,函数格式如下:

numpy.squeeze(arr, axis)
  • arr:输入数组
  • axis:整数或整数元组,用于选择形状中一维条目的子集
import numpy as npx = np.arange(9).reshape(1,3,3)print ('数组 x:')
print (x)
print ('\n')
y = np.squeeze(x)print ('数组 y:')
print (y)
print ('\n')print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
'''
数组 x:
[[[0 1 2][3 4 5][6 7 8]]]数组 y:
[[0 1 2][3 4 5][6 7 8]]数组 x 和 y 的形状:
(1, 3, 3) (3, 3)
'''

连接数组

函数 描述
concatenate 连接沿现有轴的数组序列
stack 沿着新的轴加入一系列数组。
hstack 水平堆叠序列中的数组(列方向)
vstack 竖直堆叠序列中的数组(行方向)

numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组,格式如下:

numpy.concatenate((a1, a2, ...), axis)

参数说明:

  • a1, a2, ...:相同类型的数组
  • axis:沿着它连接数组的轴,默认为 0

numpy.stack 函数用于沿新轴连接数组序列,格式如下:

numpy.stack(arrays, axis)

参数说明:

  • arrays相同形状的数组序列
  • axis:返回数组中的轴,输入数组沿着它来堆叠
# numpy.concatenate
import numpy as npa = np.array([[1,2],[3,4]])print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])print ('第二个数组:')
print (b)
print ('\n')
# 两个数组的维度相同print ('沿轴 0 连接两个数组:')
print (np.concatenate((a,b)))
print ('\n')print ('沿轴 1 连接两个数组:')
print (np.concatenate((a,b),axis = 1))
'''
第一个数组:
[[1 2][3 4]]第二个数组:
[[5 6][7 8]]沿轴 0 连接两个数组:
[[1 2][3 4][5 6][7 8]]沿轴 1 连接两个数组:
[[1 2 5 6][3 4 7 8]]
'''# numpy.stack
print ('沿轴 0 堆叠两个数组:')
print (np.stack((a,b),0))
print ('\n')print ('沿轴 1 堆叠两个数组:')
print (np.stack((a,b),1))
'''
沿轴 0 堆叠两个数组:
[[[1 2][3 4]][[5 6][7 8]]]沿轴 1 堆叠两个数组:
[[[1 2][5 6]][[3 4][7 8]]]
'''# numpy.hstack 是 numpy.stack 函数的变体,它通过水平堆叠来生成数组。
print ('水平堆叠:')
c = np.hstack((a,b))
print (c)
print ('\n')
'''
水平堆叠:
[[1 2 5 6][3 4 7 8]]
'''# numpy.vstack 是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组。
print ('竖直堆叠:')
c = np.vstack((a,b))
print (c)
'''
竖直堆叠:
[[1 2][3 4][5 6][7 8]]
'''

分割数组

函数 数组及操作
split 将一个数组分割为多个子数组
hsplit 将一个数组水平分割为多个子数组(按列)
vsplit 将一个数组垂直分割为多个子数组(按行)

numpy.split 函数沿特定的轴将数组分割为子数组,格式如下:

numpy.split(ary, indices_or_sections, axis)

参数说明:

  • ary:被分割的数组
  • indices_or_sections:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左闭右开)
  • axis:沿着哪个维度进行切向,默认为0,横向切分。为1时,纵向切分
import numpy as npa = np.arange(9)print ('第一个数组:')
print (a)
print ('\n')print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('\n')print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)
'''
第一个数组:
[0 1 2 3 4 5 6 7 8]将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]将数组在一维数组中表明的位置分割:
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
'''# numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。
harr = np.floor(10 * np.random.random((2, 6)))
print ('原array:')
print(harr)print ('拆分后:')
print(np.hsplit(harr, 3))
'''
原array:
[[4. 7. 6. 3. 2. 6.][6. 3. 6. 7. 9. 7.]]
拆分后:
[array([[4., 7.],[6., 3.]]), array([[6., 3.],[6., 7.]]), array([[2., 6.],[9., 7.]])]
'''# numpy.vsplit 沿着垂直轴分割,其分割方式与hsplit用法相同。
a = np.arange(16).reshape(4,4)print ('第一个数组:')
print (a)
print ('\n')print ('竖直分割:')
b = np.vsplit(a,2)
print (b)
'''
第一个数组:
[[ 0  1  2  3][ 4  5  6  7][ 8  9 10 11][12 13 14 15]]竖直分割:
[array([[0, 1, 2, 3],[4, 5, 6, 7]]), array([[ 8,  9, 10, 11],[12, 13, 14, 15]])]
'''

数组元素的添加与删除

resize 返回指定形状的新数组
append 将值添加到数组末尾
insert 沿指定轴将值插入到指定下标之前
delete 删掉某个轴的子数组,并返回删除后的新数组
unique 查找数组内的唯一元素

numpy.resize 函数返回指定大小的新数组。

如果新数组大小大于原始大小,则包含原始数组中的元素的副本。

numpy.resize(arr, shape)

参数说明:

  • arr:要修改大小的数组
  • shape:返回数组的新形状
import numpy as npa = np.array([[1,2,3],[4,5,6]])print ('第一个数组:')
print (a)
print ('\n')print ('第一个数组的形状:')
print (a.shape)
print ('\n')
b = np.resize(a, (3,2))print ('第二个数组:')
print (b)
print ('\n')print ('第二个数组的形状:')
print (b.shape)
print ('\n')
# 要注意 a 的第一行在 b 中重复出现,因为尺寸变大了print ('修改第二个数组的大小:')
b = np.resize(a,(3,3))
print (b)
'''
第一个数组:
[[1 2 3][4 5 6]]第一个数组的形状:
(2, 3)第二个数组:
[[1 2][3 4][5 6]]第二个数组的形状:
(3, 2)修改第二个数组的大小:
[[1 2 3][4 5 6][1 2 3]]
'''

numpy.append 函数在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。

append 函数返回的始终是一个一维数组。

numpy.append(arr, values, axis=None)

参数说明:

  • arr:输入数组
  • values:要向arr添加的值,需要和arr形状相同(除了要添加的轴)
  • axis:默认为 None。当axis无定义时,是横向加成,返回总是为一维数组!当axis有定义的时候,分别为0和1的时候。当axis有定义的时候,为0的时候(列数要相同)。当axis为1时,数组是加在右边(行数要相同)。
import numpy as npa = np.array([[1,2,3],[4,5,6]])print ('第一个数组:')
print (a)
print ('\n')print ('向数组添加元素:')
print (np.append(a, [7,8,9]))
print ('\n')print ('沿轴 0 添加元素:')
print (np.append(a, [[7,8,9]],axis = 0))
print ('\n')print ('沿轴 1 添加元素:')
print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))
'''
第一个数组:
[[1 2 3][4 5 6]]向数组添加元素:
[1 2 3 4 5 6 7 8 9]沿轴 0 添加元素:
[[1 2 3][4 5 6][7 8 9]]沿轴 1 添加元素:
[[1 2 3 5 5 5][4 5 6 7 8 9]]
'''

numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。

如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。

numpy.insert(arr, obj, values, axis)

参数说明:

  • arr:输入数组
  • obj:在其之前插入值的索引
  • values:要插入的值
  • axis:沿着它插入的轴,如果未提供,则输入数组会被展开
import numpy as npa = np.array([[1,2],[3,4],[5,6]])print ('第一个数组:')
print (a)
print ('\n')print ('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print (np.insert(a,3,[11,12]))
print ('\n')
print ('传递了 Axis 参数。 会广播值数组来配输入数组。')print ('沿轴 0 广播:')
print (np.insert(a,1,[11],axis = 0))
print ('\n')print ('沿轴 1 广播:')
print (np.insert(a,1,11,axis = 1))
'''
第一个数组:
[[1 2][3 4][5 6]]未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 1  2  3 11 12  4  5  6]传递了 Axis 参数。 会广播值数组来配输入数组。
沿轴 0 广播:
[[ 1  2][11 11][ 3  4][ 5  6]]沿轴 1 广播:
[[ 1 11  2][ 3 11  4][ 5 11  6]]
'''

numpy.delete 函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数的情况一样,如果未提供轴参数,则输入数组将展开。

Numpy.delete(arr, obj, axis)

参数说明:

  • arr:输入数组
  • obj:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组
  • axis:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
import numpy as npa = np.arange(12).reshape(3,4)print ('第一个数组:')
print (a)
print ('\n')print ('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print (np.delete(a,5))
print ('\n')print ('删除第二列:')
print (np.delete(a,1,axis = 1))
print ('\n')print ('包含从数组中删除的替代值的切片:')
a = np.array([1,2,3,4,5,6,7,8,9,10])
print (np.delete(a, np.s_[::2]))
'''
第一个数组:
[[ 0  1  2  3][ 4  5  6  7][ 8  9 10 11]]未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 0  1  2  3  4  6  7  8  9 10 11]删除第二列:
[[ 0  2  3][ 4  6  7][ 8 10 11]]包含从数组中删除的替代值的切片:
[ 2  4  6  8 10]
'''

numpy.unique 函数用于去除数组中的重复元素。

numpy.unique(arr, return_index, return_inverse, return_counts)
  • arr:输入数组,如果不是一维数组则会展开
  • return_index:如果为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储
  • return_inverse:如果为true,返回旧列表元素在新列表中的位置(下标),并以列表形式储
  • return_counts:如果为true,返回去重数组中的元素在原数组中的出现次数
import numpy as npa = np.array([5,2,6,2,7,5,6,8,2,9])print ('第一个数组:')
print (a)
print ('\n')print ('第一个数组的去重值:')
u = np.unique(a)
print (u)
print ('\n')print ('去重数组的索引数组:')
u,indices = np.unique(a, return_index = True)
print (indices)
print ('\n')print ('我们可以看到每个和原数组下标对应的数值:')
print (a)
print ('\n')print ('去重数组的下标:')
u,indices = np.unique(a,return_inverse = True)
print (u)
print ('\n')print ('下标为:')
print (indices)
print ('\n')print ('使用下标重构原数组:')
print (u[indices])
print ('\n')print ('返回去重元素的重复数量:')
u,indices = np.unique(a,return_counts = True)
print (u)
print (indices)
'''
第一个数组:
[5 2 6 2 7 5 6 8 2 9]第一个数组的去重值:
[2 5 6 7 8 9]去重数组的索引数组:
[1 0 2 4 7 9]我们可以看到每个和原数组下标对应的数值:
[5 2 6 2 7 5 6 8 2 9]去重数组的下标:
[2 5 6 7 8 9]下标为:
[1 0 2 0 3 1 2 4 0 5]使用下标重构原数组:
[5 2 6 2 7 5 6 8 2 9]返回去重元素的重复数量:
[2 5 6 7 8 9]
[3 2 2 1 1 1]
'''

三、numpy运算

位运算

NumPy “bitwise_” 开头的函数是位运算函数。

NumPy 位运算包括以下几个函数:

函数 描述
bitwise_and 对数组元素执行位与操作
bitwise_or 对数组元素执行位或操作
invert 按位取反
left_shift 向左移动二进制表示的位
right_shift 向右移动二进制表示的位

**注:**也可以使用 “&”、 “~”、 “|” 和 “^” 等操作符进行计算。

bitwise_and() 函数对数组中整数的二进制形式执行位与运算。

import numpy as np print ('13 和 17 的二进制形式:')
a,b = 13,17
print (bin(a), bin(b))
print ('\n')print ('13 和 17 的位与:')
print (np.bitwise_and(13, 17))
'''
13 和 17 的二进制形式:
0b1101 0b1000113 和 17 的位与:
1
'''

以上实例可以用下表来说明:

1 1 0 1
AND
1 0 0 0 1
运算结果 0 0 0 0 1

位与操作运算规律如下:

A B AND
1 1 1
1 0 0
0 1 0
0 0 0

bitwise_or()函数对数组中整数的二进制形式执行位或运算。

import numpy as np a,b = 13,17
print ('13 和 17 的二进制形式:')
print (bin(a), bin(b))print ('13 和 17 的位或:')
print (np.bitwise_or(13, 17))
'''
13 和 17 的二进制形式:
0b1101 0b10001
13 和 17 的位或:
29
'''

以上实例可以用下表来说明:

1 1 0 1
OR
1 0 0 0 1
运算结果 1 1 1 0 1

位或操作运算规律如下:

A B OR
1 1 1
1 0 1
0 1 1
0 0 0

invert() 函数对数组中整数进行位取反运算,即 0 变成 1,1 变成 0。

对于有符号整数,取该二进制数的补码,然后 +1。二进制数,最高位为0表示正数,最高位为 1 表示负数。

看看 ~1 的计算步骤:

  • 将**1**(这里叫:原码)转二进制 = 00000001
  • 按位取反 = 11111110
  • 发现符号位(即最高位)为**1**(表示负数),将除符号位之外的其他数字取反 = 10000001
  • 末位加1取其补码 = 10000010
  • 转换回十进制 = -2
表达式 二进制值(2 的补数) 十进制值
~5 11111111 11111111 11111111 11111010 -6
import numpy as np print ('13 的位反转,其中 ndarray 的 dtype 是 uint8:')
print (np.invert(np.array([13], dtype = np.uint8)))
print ('\n')
# 比较 13 和 242 的二进制表示,我们发现了位的反转print ('13 的二进制表示:')
print (np.binary_repr(13, width = 8))
print ('\n')print ('242 的二进制表示:')
print (np.binary_repr(242, width = 8))
'''
13 的位反转,其中 ndarray 的 dtype 是 uint8:
[242]13 的二进制表示:
00001101242 的二进制表示:
11110010
'''# left_shift() 函数将数组元素的二进制形式向左移动到指定位置,右侧附加相等数量的 0。
import numpy as np print ('将 10 左移两位:')
print (np.left_shift(10,2))
print ('\n')print ('10 的二进制表示:')
print (np.binary_repr(10, width = 8))
print ('\n')print ('40 的二进制表示:')
print (np.binary_repr(40, width = 8))
#  '00001010' 中的两位移动到了左边,并在右边添加了两个 0。
'''
将 10 左移两位:
4010 的二进制表示:
0000101040 的二进制表示:
00101000
'''# right_shift() 函数将数组元素的二进制形式向右移动到指定位置,左侧附加相等数量的 0。
import numpy as np print ('将 40 右移两位:')
print (np.right_shift(40,2))
print ('\n')print ('40 的二进制表示:')
print (np.binary_repr(40, width = 8))
print ('\n')print ('10 的二进制表示:')
print (np.binary_repr(10, width = 8))
#  '00001010' 中的两位移动到了右边,并在左边添加了两个 0。
'''
将 40 右移两位:
1040 的二进制表示:
0010100010 的二进制表示:
00001010
'''

字符串函数

以下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作。 它们基于 Python 内置库中的标准字符串函数。

这些函数在字符数组类(numpy.char)中定义。

函数 描述
add() 对两个数组的逐个字符串元素进行连接
multiply() 返回按元素多重连接后的字符串
center() 居中字符串
capitalize() 将字符串第一个字母转换为大写
title() 将字符串的每个单词的第一个字母转换为大写
lower() 数组元素转换为小写
upper() 数组元素转换为大写
split() 指定分隔符对字符串进行分割,并返回数组列表
splitlines() 返回元素中的行列表,以换行符分割
strip() 移除元素开头或者结尾处的特定字符
join() 通过指定分隔符来连接数组中的元素
replace() 使用新字符串替换字符串中的所有子字符串
decode() 数组元素依次调用str.decode
encode() 数组元素依次调用str.encode
# numpy.char.add() 函数依次对两个数组的元素进行字符串连接。
import numpy as np print ('连接两个字符串:')
print (np.char.add(['hello'],[' xyz']))
print ('\n')print ('连接示例:')
print (np.char.add(['hello', 'hi'],[' abc', ' xyz']))
'''
连接两个字符串:
['hello xyz']连接示例:
['hello abc' 'hi xyz']
'''# numpy.char.multiply() 函数执行多重连接。
print (np.char.multiply('Runoob ',3))
'''
Runoob Runoob Runoob
'''# numpy.char.center() 函数用于将字符串居中,并使用指定字符在左侧和右侧进行填充。
# np.char.center(str , width,fillchar) :
# str: 字符串,width: 长度,fillchar: 填充字符
print (np.char.center('Runoob', 20,fillchar = '*'))
'''
*******Runoob*******
'''# numpy.char.capitalize() 函数将字符串的第一个字母转换为大写:
print (np.char.capitalize('runoob'))
'''
Runoob
'''# numpy.char.title() 函数将字符串的每个单词的第一个字母转换为大写:
print (np.char.title('i like runoob'))
'''
I Like Runoob
'''# numpy.char.lower() 函数对数组的每个元素转换为小写。它对每个元素调用 str.lower。
#操作数组
print (np.char.lower(['RUNOOB','GOOGLE']))# 操作字符串
print (np.char.lower('RUNOOB'))
'''
['runoob' 'google']
runoob
'''# numpy.char.upper() 函数对数组的每个元素转换为大写。它对每个元素调用 str.upper。
#操作数组
print (np.char.upper(['runoob','google']))# 操作字符串
print (np.char.upper('runoob'))
'''
['RUNOOB' 'GOOGLE']
RUNOOB
'''# numpy.char.split() 通过指定分隔符对字符串进行分割,并返回数组。默认情况下,分隔符为空格。
# 分隔符默认为空格
print (np.char.split ('i like runoob?'))
# 分隔符为 .
print (np.char.split ('www.runoob.com', sep = '.'))
'''
['i', 'like', 'runoob?']
['www', 'runoob', 'com']
'''# numpy.char.splitlines() 函数以换行符作为分隔符来分割字符串,并返回数组。
# 换行符 \n
print (np.char.splitlines('i\nlike runoob?'))
print (np.char.splitlines('i\rlike runoob?'))
'''
['i', 'like runoob?']
['i', 'like runoob?']
'''
# \n,\r,\r\n 都可用作换行符。# numpy.char.strip() 函数用于移除开头或结尾处的特定字符。
# 移除字符串头尾的 a 字符
print (np.char.strip('ashok arunooba','a'))# 移除数组元素头尾的 a 字符
print (np.char.strip(['arunooba','admin','java'],'a'))
'''
shok arunoob
['runoob' 'dmin' 'jav']
'''# numpy.char.join() 函数通过指定分隔符来连接数组中的元素或字符串
# 操作字符串
print (np.char.join(':','runoob'))# 指定多个分隔符操作数组元素
print (np.char.join([':','-'],['runoob','google']))
'''
r:u:n:o:o:b
['r:u:n:o:o:b' 'g-o-o-g-l-e'
'''# numpy.char.replace() 函数使用新字符串替换字符串中的所有子字符串。
print (np.char.replace ('i like runoob', 'oo', 'cc'))
'''
i like runccb
'''# numpy.char.encode() 函数对数组中的每个元素调用 str.encode 函数。 默认编码是 utf-8,可以使用标准 Python 库中的编解码器
a = np.char.encode('runoob', 'cp500')
print (a)
'''
b'\x99\xa4\x95\x96\x96\x82'
'''
# numpy.char.decode() 函数对编码的元素进行 str.decode() 解码。
print (np.char.decode(a,'cp500'))
'''
runoob
'''

数学函数

NumPy 包含大量的各种数学运算的函数,包括三角函数,算术运算的函数,复数处理函数等。

NumPy 提供了标准的三角函数:sin()、cos()、tan()。反三角函数:arcsin,arccos,和 arctan ,反三角函数的结果可以通过 numpy.degrees() 函数将弧度转换为角度。

numpy.around() 函数返回指定数字的四舍五入值。

numpy.around(a,decimals)

参数说明:

  • a: 数组
  • decimals: 舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置
import numpy as npa = np.array([1.0,5.55,  123,  0.567,  25.532])
print  ('原数组:')
print (a)
print ('\n')
print ('舍入后:')
print (np.around(a))
print (np.around(a, decimals =  1))
print (np.around(a, decimals =  -1))
'''
原数组:
[  1.      5.55  123.      0.567  25.532]舍入后:
[  1.   6. 123.   1.  26.]
[  1.    5.6 123.    0.6  25.5]
[  0.  10. 120.   0.  30.]
'''# numpy.floor() 返回小于或者等于指定表达式的最大整数,即向下取整。
a = np.array([-1.7,  1.5,  -0.2,  0.6,  10])
print ('提供的数组:')
print (a)
print ('\n')
print ('修改后的数组:')
print (np.floor(a))
'''
提供的数组:
[-1.7  1.5 -0.2  0.6 10. ]修改后的数组:
[-2.  1. -1.  0. 10.]
'''# numpy.ceil() 返回大于或者等于指定表达式的最小整数,即向上取整。
print (np.ceil(a))
'''
[-1.  2. -0.  1. 10.]
'''

算术函数

NumPy 算术函数包含简单的加减乘除: add()subtract()multiply()divide()

需要注意的是数组必须具有相同的形状或符合数组广播规则。

import numpy as np a = np.arange(9, dtype = np.float_).reshape(3,3)
print ('第一个数组:')
print (a)
print ('\n')
print ('第二个数组:')
b = np.array([10,10,10])
print (b)
print ('\n')
print ('两个数组相加:')
print (np.add(a,b))
print ('\n')
print ('两个数组相减:')
print (np.subtract(a,b))
print ('\n')
print ('两个数组相乘:')
print (np.multiply(a,b))
print ('\n')
print ('两个数组相除:')
print (np.divide(a,b))
'''
第一个数组:
[[0. 1. 2.][3. 4. 5.][6. 7. 8.]]第二个数组:
[10 10 10]两个数组相加:
[[10. 11. 12.][13. 14. 15.][16. 17. 18.]]两个数组相减:
[[-10.  -9.  -8.][ -7.  -6.  -5.][ -4.  -3.  -2.]]两个数组相乘:
[[ 0. 10. 20.][30. 40. 50.][60. 70. 80.]]两个数组相除:
[[0.  0.1 0.2][0.3 0.4 0.5][0.6 0.7 0.8]]
'''

此外 Numpy 也包含了其他重要的算术函数。

# numpy.reciprocal() 函数返回参数元素的倒数。如 1/4 倒数为 4/1。import numpy as np a = np.array([0.25,  1.33,  1,  100])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 reciprocal 函数:')
print (np.reciprocal(a))
'''
我们的数组是:
[  0.25   1.33   1.   100.  ]调用 reciprocal 函数:
[4.        0.7518797 1.        0.01     ]
'''# numpy.power() 函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。
a = np.array([10,100,1000])
print ('我们的数组是;')
print (a)
print ('\n')
print ('调用 power 函数:')
print (np.power(a,2))
print ('\n')
print ('第二个数组:')
b = np.array([1,2,3])
print (b)
print ('\n')
print ('再次调用 power 函数:')
print (np.power(a,b))
'''
我们的数组是;
[  10  100 1000]调用 power 函数:
[    100   10000 1000000]第二个数组:
[1 2 3]再次调用 power 函数:
[        10      10000 1000000000]
'''# numpy.mod() 计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果。
a = np.array([10,20,30])
b = np.array([3,5,7])
print ('第一个数组:')
print (a)
print ('\n')
print ('第二个数组:')
print (b)
print ('\n')
print ('调用 mod() 函数:')
print (np.mod(a,b))
print ('\n')
print ('调用 remainder() 函数:')
print (np.remainder(a,b))
'''
第一个数组:
[10 20 30]第二个数组:
[3 5 7]调用 mod() 函数:
[1 0 2]调用 remainder() 函数:
[1 0 2]
'''

统计函数

NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等。 函数说明如下:

numpy.amin() 用于计算数组中的元素沿指定轴的最小值。

numpy.amax() 用于计算数组中的元素沿指定轴的最大值。

numpy.ptp()函数计算数组中元素最大值与最小值的差(最大值 - 最小值)。

import numpy as np a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 amin() 函数:')
print (np.amin(a,1))
print ('\n')
print ('再次调用 amin() 函数:')
print (np.amin(a,0))
print ('\n')
print ('调用 amax() 函数:')
print (np.amax(a))
print ('\n')
print ('再次调用 amax() 函数:')
print (np.amax(a, axis =  0))
'''
我们的数组是:
[[3 7 5][8 4 3][2 4 9]]调用 amin() 函数:
[3 3 2]再次调用 amin() 函数:
[2 4 3]调用 amax() 函数:
9再次调用 amax() 函数:
[8 7 9]
'''print (np.ptp(a, axis =  1))
print (np.ptp(a, axis =  0))
'''
[4 5 7]
[6 3 6]
'''

百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。 函数numpy.percentile()接受以下参数。

numpy.percentile(a, q, axis)

参数说明:

  • a: 输入数组
  • q: 要计算的百分位数,在 0 ~ 100 之间
  • axis: 沿着它计算百分位数的轴

首先明确百分位数:

第 p 个百分位数是这样一个值,它使得至少有 p% 的数据项小于或等于这个值,且至少有 (100-p)% 的数据项大于或等于这个值。

举个例子:高等院校的入学考试成绩经常以百分位数的形式报告。比如,假设某个考生在入学考试中的语文部分的原始分数为 54 分。相对于参加同一考试的其他学生来说,他的成绩如何并不容易知道。但是如果原始分数54分恰好对应的是第70百分位数,我们就能知道大约70%的学生的考分比他低,而约30%的学生考分比他高。

这里的 p = 70。

import numpy as np a = np.array([[10, 7, 4], [3, 2, 1]])
print ('我们的数组是:')
print (a)print ('调用 percentile() 函数:')
# 50% 的分位数,就是 a 里排序之后的中位数
print (np.percentile(a, 50)) # axis 为 0,在纵列上求
print (np.percentile(a, 50, axis=0)) # axis 为 1,在横行上求
print (np.percentile(a, 50, axis=1)) # 保持维度不变
print (np.percentile(a, 50, axis=1, keepdims=True))
'''
我们的数组是:
[[10  7  4][ 3  2  1]]
调用 percentile() 函数:
3.5
[6.5 4.5 2.5]
[7. 2.]
[[7.][2.]]
'''

numpy.median() 函数用于计算数组 a 中元素的中位数(中值)

import numpy as np a = np.array([[30,65,70],[80,95,10],[50,90,60]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 median() 函数:')
print (np.median(a))
print ('\n')
print ('沿轴 0 调用 median() 函数:')
print (np.median(a, axis =  0))
print ('\n')
print ('沿轴 1 调用 median() 函数:')
print (np.median(a, axis =  1))
'''
我们的数组是:
[[30 65 70][80 95 10][50 90 60]]调用 median() 函数:
65.0沿轴 0 调用 median() 函数:
[50. 90. 60.]沿轴 1 调用 median() 函数:
[65. 80. 60.]
'''

numpy.mean() 函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。

算术平均值是沿轴的元素的总和除以元素的数量。

import numpy as np a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 mean() 函数:')
print (np.mean(a))
print ('\n')
print ('沿轴 0 调用 mean() 函数:')
print (np.mean(a, axis =  0))
print ('\n')
print ('沿轴 1 调用 mean() 函数:')
print (np.mean(a, axis =  1))
'''
我们的数组是:
[[1 2 3][3 4 5][4 5 6]]调用 mean() 函数:
3.6666666666666665沿轴 0 调用 mean() 函数:
[2.66666667 3.66666667 4.66666667]沿轴 1 调用 mean() 函数:
[2. 4. 5.]
'''

numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。

该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。

加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。

考虑数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。

加权平均值 = (1*4+2*3+3*2+4*1)/(4+3+2+1)
import numpy as np a = np.array([1,2,3,4])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 average() 函数:')
print (np.average(a))
print ('\n')
# 不指定权重时相当于 mean 函数
wts = np.array([4,3,2,1])
print ('再次调用 average() 函数:')
print (np.average(a,weights = wts))
print ('\n')
# 如果 returned 参数设为 true,则返回权重的和
print ('权重的和:')
print (np.average([1,2,3,  4],weights =  [4,3,2,1], returned =  True))
'''
我们的数组是:
[1 2 3 4]调用 average() 函数:
2.5再次调用 average() 函数:
2.0权重的和:
(2.0, 10.
'''# 在多维数组中,可以指定用于计算的轴。
import numpy as np a = np.arange(6).reshape(3,2)
print ('我们的数组是:')
print (a)
print ('\n')
print ('修改后的数组:')
wt = np.array([3,5])
print (np.average(a, axis =  1, weights = wt))
print ('\n')
print ('修改后的数组:')
print (np.average(a, axis =  1, weights = wt, returned =  True))
'''
我们的数组是:
[[0 1][2 3][4 5]]修改后的数组:
[0.625 2.625 4.625]修改后的数组:
(array([0.625, 2.625, 4.625]), array([8., 8., 8.]))
'''

方差

统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即 mean((x - x.mean())** 2)。

如果数组是 [1,2,3,4],则其平均值为 2.5。 因此,差的平方是 [2.25,0.25,0.25,2.25],所有5/4=1.25

标准差

标准差是一组数据平均值分散程度的一种度量。标准差是方差的算术平方根。标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值

反映出数据的波动稳定情况,越大表示波动越大,约不稳定

标准差公式如下:std = sqrt(mean((x - x.mean())**2))

换句话说,标准差是方差的平方根。

如果数组是 [1,2,3,4],则其平均值为 2.5。 因此,差的平方是 [2.25,0.25,0.25,2.25],并且再求其平均值的平方根除以 4,即 sqrt(5/4) ,结果为 1.1180339887498949。

import numpy as npprint (np.var([1,2,3,4]))
'''
1.25
'''# 标准差
print (np.std([1,2,3,4]))
'''
1.1180339887498949
'''

排序、条件刷选函数

NumPy 提供了多种排序的方法。 这些排序函数实现不同的排序算法,每个排序算法的特征在于执行速度,最坏情况性能,所需的工作空间和算法的稳定性。 下表显示了三种排序算法的比较。

种类 速度 最坏情况 工作空间 稳定性
'quicksort'(快速排序) 1 O(n^2) 0
'mergesort'(归并排序) 2 O(n*log(n)) ~n/2
'heapsort'(堆排序) 3 O(n*log(n)) 0

numpy.sort() 函数返回输入数组的排序副本。函数格式如下:

numpy.sort(a, axis, kind, order)

参数说明:

  • a: 要排序的数组
  • axis: 沿着它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序, axis=0 按列排序,axis=1 按行排序
  • kind: 默认为’quicksort’(快速排序)
  • order: 如果数组包含字段,则是要排序的字段
import numpy as np  a = np.array([[3,7],[9,1]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 sort() 函数:')
print (np.sort(a))
print ('\n')
print ('按列排序:')
print (np.sort(a, axis =  0))
print ('\n')
# 在 sort 函数中排序字段
dt = np.dtype([('name',  'S10'),('age',  int)])
a = np.array([("raju",21),("anil",25),("ravi",  17),  ("amar",27)], dtype = dt)
print ('我们的数组是:')
print (a)
print ('\n')
print ('按 name 排序:')
print (np.sort(a, order =  'name'))
'''
我们的数组是:
[[3 7][9 1]]调用 sort() 函数:
[[3 7][1 9]]按列排序:
[[3 1][9 7]]我们的数组是:
[(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]按 name 排序:
[(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]
'''# numpy.argsort() 函数返回的是数组值从小到大的索引值。
x = np.array([3,  1,  2])
print ('我们的数组是:')
print (x)
print ('\n')
print ('对 x 调用 argsort() 函数:')
y = np.argsort(x)
print (y)
print ('\n')
print ('以排序后的顺序重构原数组:')
print (x[y])
print ('\n')
print ('使用循环重构原数组:')
for i in y:  print (x[i], end=" ")
'''
我们的数组是:
[3 1 2]对 x 调用 argsort() 函数:
[1 2 0]以排序后的顺序重构原数组:
[1 2 3]使用循环重构原数组1 2 3
'''# numpy.lexsort() 用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。这里举一个应用场景:小升初考试,重点班录取学生按照总成绩录取。在总成绩相同时,数学成绩高的优先录取,在总成绩和数学成绩都相同时,按照英语成绩录取…… 这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。nm =  ('raju','anil','ravi','amar')
dv =  ('f.y.',  's.y.',  's.y.',  'f.y.')
ind = np.lexsort((dv,nm))
print ('调用 lexsort() 函数:')
print (ind)
print ('\n')
print ('使用这个索引来获取排序后的数据:')
print ([nm[i]  +  ", "  + dv[i]  for i in ind])
'''
调用 lexsort() 函数:
[3 1 0 2]使用这个索引来获取排序后的数据:
['amar, f.y.', 'anil, s.y.', 'raju, f.y.', 'ravi, s.y.']
'''
# 上面传入 np.lexsort 的是一个tuple,排序时首先排 nm,顺序为:amar、anil、raju、ravi 。综上排序结果为 [3 1 0 2]。

numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。

import numpy as np a = np.array([[30,40,70],[80,20,10],[50,90,60]])
print  ('我们的数组是:')
print (a)
print ('\n')
print ('调用 argmax() 函数:')
print (np.argmax(a))
print ('\n')
print ('展开数组:')
print (a.flatten())
print ('\n')
print ('沿轴 0 的最大值索引:')
maxindex = np.argmax(a, axis =  0)
print (maxindex)
print ('\n')
print ('沿轴 1 的最大值索引:')
maxindex = np.argmax(a, axis =  1)
print (maxindex)
print ('\n')
print ('调用 argmin() 函数:')
minindex = np.argmin(a)
print (minindex)
print ('\n')
print ('展开数组中的最小值:')
print (a.flatten()[minindex])
print ('\n')
print ('沿轴 0 的最小值索引:')
minindex = np.argmin(a, axis =  0)
print (minindex)
print ('\n')
print ('沿轴 1 的最小值索引:')
minindex = np.argmin(a, axis =  1)
print (minindex)
'''
我们的数组是:
[[30 40 70][80 20 10][50 90 60]]调用 argmax() 函数:
7展开数组:
[30 40 70 80 20 10 50 90 60]沿轴 0 的最大值索引:
[1 2 0]沿轴 1 的最大值索引:
[2 0 1]调用 argmin() 函数:
5展开数组中的最小值:
10沿轴 0 的最小值索引:
[0 1 1]沿轴 1 的最小值索引:
[0 2 0]
'''

numpy.nonzero() 函数返回输入数组中非零元素的索引。

import numpy as np a = np.array([[30,40,0],[0,20,10],[50,0,60]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 nonzero() 函数:')
print (np.nonzero (a))
'''
我们的数组是:
[[30 40  0][ 0 20 10][50  0 60]]调用 nonzero() 函数:
(array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))
'''# numpy.where() 函数返回输入数组中满足给定条件的元素的索引。
x = np.arange(9.).reshape(3,  3)
print ('我们的数组是:')
print (x)
print ( '大于 3 的元素的索引:')
y = np.where(x >  3)
print (y)
print ('使用这些索引来获取满足条件的元素:')
print (x[y])
'''
我们的数组是:
[[0. 1. 2.][3. 4. 5.][6. 7. 8.]]
大于 3 的元素的索引:
(array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))
使用这些索引来获取满足条件的元素:
[4. 5. 6. 7. 8.]
'''# numpy.extract() 函数根据某个条件从数组中抽取元素,返回满条件的元素。
x = np.arange(9.).reshape(3,  3)
print ('我们的数组是:')
print (x)
# 定义条件, 选择偶数元素
condition = np.mod(x,2)  ==  0
print ('按元素的条件值:')
print (condition)
print ('使用条件提取元素:')
print (np.extract(condition, x))
'''
我们的数组是:
[[0. 1. 2.][3. 4. 5.][6. 7. 8.]]
按元素的条件值:
[[ True False  True][False  True False][ True False  True]]
使用条件提取元素:
[0. 2. 4. 6. 8.]
'''

副本和视图

副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置。

视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置。

视图一般发生在:

  • 1、numpy 的切片操作返回原数据的视图。
  • 2、调用 ndarray 的 view() 函数产生一个视图。

副本一般发生在:

  • Python 序列的切片操作,调用deepCopy()函数。
  • 调用 ndarray 的 copy() 函数产生一个副本。

无复制

简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同id()来访问它。 id()返回 Python 对象的通用标识符,类似于 C 中的指针。此外,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。

import numpy as np a = np.arange(6)
print ('我们的数组是:')
print (a)
print ('调用 id() 函数:')
print (id(a))
print ('a 赋值给 b:')
b = a
print (b)
print ('b 拥有相同 id():')
print (id(b))
print ('修改 b 的形状:')
b.shape =  3,2
print (b)
print ('a 的形状也修改了:')
print (a)
'''
我们的数组是:
[0 1 2 3 4 5]
调用 id() 函数:
4349302224
a 赋值给 b:
[0 1 2 3 4 5]
b 拥有相同 id():
4349302224
修改 b 的形状:
[[0 1][2 3][4 5]]
a 的形状也修改了:
[[0 1][2 3][4 5]]
'''

视图或浅拷贝

ndarray.view() 方会创建一个新的数组对象,该方法创建的新数组的维数更改不会更改原始数据的维数。

import numpy as np # 最开始 a 是个 3X2 的数组
a = np.arange(6).reshape(3,2)
print ('数组 a:')
print (a)
print ('创建 a 的视图:')
b = a.view()
print (b)
print ('两个数组的 id() 不同:')
print ('a 的 id():')
print (id(a))
print ('b 的 id():' )
print (id(b))
# 修改 b 的形状,并不会修改 a
b.shape =  2,3
print ('b 的形状:')
print (b)
print ('a 的形状:')
print (a)
'''
数组 a:
[[0 1][2 3][4 5]]
创建 a 的视图:
[[0 1][2 3][4 5]]
两个数组的 id() 不同:
a 的 id():
4314786992
b 的 id():
4315171296
b 的形状:
[[0 1 2][3 4 5]]
a 的形状:
[[0 1][2 3][4 5]]
'''# 使用切片创建视图修改数据会影响到原始数组:
arr = np.arange(12)
print ('我们的数组:')
print (arr)
print ('创建切片:')
a=arr[3:]
b=arr[3:]
a[1]=123
b[2]=234
print(arr)
print(id(a),id(b),id(arr[3:]))
'''
我们的数组:
[ 0  1  2  3  4  5  6  7  8  9 10 11]
创建切片:
[  0   1   2   3 123 234   6   7   8   9  10  11]
4545878416 4545878496 4545878576
'''# 变量 a,b 都是 arr 的一部分视图,对视图的修改会直接反映到原数据中。但是我们观察 a,b 的 id,他们是不同的,也就是说,视图虽然指向原数据,但是他们和赋值引用还是有区别的。

副本或深拷贝

ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。

import numpy as np a = np.array([[10,10],  [2,3],  [4,5]])
print ('数组 a:')
print (a)
print ('创建 a 的深层副本:')
b = a.copy()
print ('数组 b:')
print (b)
# b 与 a 不共享任何内容
print ('我们能够写入 b 来写入 a 吗?')
print (b is a)
print ('修改 b 的内容:')
b[0,0]  =  100
print ('修改后的数组 b:')
print (b)
print ('a 保持不变:')
print (a)
'''
数组 a:
[[10 10][ 2  3][ 4  5]]
创建 a 的深层副本:
数组 b:
[[10 10][ 2  3][ 4  5]]
我们能够写入 b 来写入 a 吗?
False
修改 b 的内容:
修改后的数组 b:
[[100  10][  2   3][  4   5]]
a 保持不变:
[[10 10][ 2  3][ 4  5]]
'''

矩阵库(Matrix)

NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
一个 矩阵是由行(row)列(column)元素排列成的矩形阵列。
矩阵里的元素可以是数字、符号或数学式。以下是一个由 6 个数字元素构成的 2 行 3 列的矩阵:

转置矩阵

NumPy 中除了可以使用 numpy.transpose 函数来对换数组的维度,还可以使用 T 属性。。

例如有个 m 行 n 列的矩阵,使用 t() 函数就能转换为 n 行 m 列的矩阵。

import numpy as npa = np.arange(12).reshape(3,4)print ('原数组:')
print (a)
print ('\n')print ('转置数组:')
print (a.T)
'''
原数组:
[[ 0  1  2  3][ 4  5  6  7][ 8  9 10 11]]转置数组:
[[ 0  4  8][ 1  5  9][ 2  6 10][ 3  7 11]]
'''

matlib.empty() 函数返回一个新的矩阵,语法格式为:

numpy.matlib.empty(shape, dtype, order)

参数说明:

  • shape: 定义新矩阵形状的整数或整数元组
  • Dtype: 可选,数据类型
  • order: C(行序优先) 或者 F(列序优先)

numpy.matlib.zeros() 函数创建一个以 0 填充的矩阵。

**numpy.matlib.ones()**函数创建一个以 1 填充的矩阵。

numpy.matlib.eye() 函数返回一个矩阵,对角线元素为 1,其他位置为零。

numpy.matlib.eye(n, M,k, dtype)

参数说明:

  • n: 返回矩阵的行数
  • M: 返回矩阵的列数,默认为 n
  • k: 对角线的索引
  • dtype: 数据类型

numpy.matlib.identity() 函数返回给定大小的单位矩阵。

单位矩阵是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为 1,除此以外全都为 0。

numpy.matlib.rand() 函数创建一个给定大小的矩阵,数据是随机填充的。

实例

# matlib.empty
import numpy.matlib
import numpy as npprint (np.matlib.empty((2,2)))
# 填充为随机数据
'''
[[-1.49166815e-154 -1.49166815e-154][ 2.17371491e-313  2.52720790e-212]]
'''# numpy.matlib.zeros
print (np.matlib.zeros((2,2)))
'''
[[0. 0.][0. 0.]]
'''# numpy.matlib.ones
print (np.matlib.ones((2,2)))
'''
[[1. 1.][1. 1.]]
'''# numpy.matlib.eye
print (np.matlib.eye(n =  3, M =  4, k =  0, dtype =  float))
'''
[[1. 0. 0. 0.][0. 1. 0. 0.][0. 0. 1. 0.]]
'''# numpy.matlib.identity
# 大小为 5,类型位浮点型
print (np.matlib.identity(5, dtype =  float))
'''
[[ 1.  0.  0.  0.  0.] [ 0.  1.  0.  0.  0.] [ 0.  0.  1.  0.  0.] [ 0.  0.  0.  1.  0.] [ 0.  0.  0.  0.  1.]]
'''# numpy.matlib.rand
print (np.matlib.rand(3,3))
'''
[[0.23966718 0.16147628 0.14162   ][0.28379085 0.59934741 0.62985825][0.99527238 0.11137883 0.41105367]]
'''
# 矩阵总是二维的,而 ndarray 是一个 n 维数组。 两个对象都是可互换的
i = np.matrix('1,2;3,4')
print (i)
'''
[[1  2] [3  4]]
'''
j = np.asarray(i)   # 转换为ndarray对象
print (j)
'''
[[1  2] [3  4]]
'''k = np.asmatrix (j)  # 转换为矩阵
print (k)
'''
[[1  2] [3  4]]
'''

NumPy IO

Numpy 可以读写磁盘上的文本数据或二进制数据。

NumPy 为 ndarray 对象引入了一个简单的文件格式:npy

npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。

常用的 IO 函数有:

  • load() 和 save() 函数是读写文件数组数据的两个主要函数,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 .npy 的文件中。

  • savez() 函数用于将多个数组写入文件,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 .npz 的文件中。

  • loadtxt() 和 savetxt() 函数处理正常的文本文件(.txt 等)

numpy.save()

numpy.save() 函数将数组保存到以 .npy 为扩展名的文件中。

numpy.save(file, arr, allow_pickle=True, fix_imports=True)

参数说明:

  • file:要保存的文件,扩展名为 .npy,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上。
  • arr: 要保存的数组
  • allow_pickle: 可选,布尔值,允许使用 Python pickles 保存对象数组,Python 中的 pickle 用于在保存到磁盘文件或从磁盘文件读取之前,对对象进行序列化和反序列化。
  • fix_imports: 可选,为了方便 Pyhton2 中读取 Python3 保存的数据。
import numpy as np a = np.array([1,2,3,4,5]) # 保存到 outfile.npy 文件上
np.save('outfile.npy',a) # 保存到 outfile2.npy 文件上,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上
np.save('outfile2',a)# 使用 load() 函数来读取数据
b = np.load('outfile.npy')
print (b)
'''
[1 2 3 4 5]
'''

np.savez

numpy.savez() 函数将多个数组保存到以 npz 为扩展名的文件中。

numpy.savez(file, *args, **kwds)

参数说明:

  • file:要保存的文件,扩展名为 .npz,如果文件路径末尾没有扩展名 .npz,该扩展名会被自动加上。
  • args: 要保存的数组,可以使用关键字参数为数组起一个名字,非关键字参数传递的数组会自动起名为 arr_0, arr_1, … 。
  • kwds: 要保存的数组使用关键字名称。
import numpy as np a = np.array([[1,2,3],[4,5,6]])
b = np.arange(0, 1.0, 0.1)
c = np.sin(b)
# c 使用了关键字参数 sin_array
np.savez("runoob.npz", a, b, sin_array = c)
r = np.load("runoob.npz")
print(r.files) # 查看各个数组名称
print(r["arr_0"]) # 数组 a
print(r["arr_1"]) # 数组 b
print(r["sin_array"]) # 数组 c
'''
['sin_array', 'arr_0', 'arr_1']
[[1 2 3][4 5 6]]
[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
[0.         0.09983342 0.19866933 0.29552021 0.38941834 0.479425540.56464247 0.64421769 0.71735609 0.78332691]
'''

savetxt()

savetxt() 函数是以简单的文本文件格式存储数据,对应的使用 loadtxt() 函数来获取数据。

np.loadtxt(FILENAME, dtype=int, delimiter=' ')
np.savetxt(FILENAME, a, fmt="%d", delimiter=",")

参数 delimiter 可以指定各种分隔符、针对特定列的转换器函数、需要跳过的行数等。

import numpy as np a = np.array([1,2,3,4,5])
np.savetxt('out.txt',a)
b = np.loadtxt('out.txt')
print(b)
'''
[1. 2. 3. 4. 5.]
'''# 使用 delimiter 参数:
a=np.arange(0,10,0.5).reshape(4,-1)
np.savetxt("out.txt",a,fmt="%d",delimiter=",") # 改为保存为整数,以逗号分隔
b = np.loadtxt("out.txt",delimiter=",") # load 时也要指定为逗号分隔
print(b)
'''
[[0. 0. 1. 1. 2.][2. 3. 3. 4. 4.][5. 5. 6. 6. 7.][7. 8. 8. 9. 9.]]
'''

numpy中三元运算符:

numpy.where(t<10,0,20),把数组中小于10的赋值为0,大于10的赋值为20

numpy中的clip(裁剪):

numpy.clip(10,20),把数组中小于10的赋值为10,大于20的赋值为20

numpy中的nan和inf:

nan(NAN,Nan):not a number表示不是一个数字

什么时候numpy中会出现nan:

  • 当我们读取本地的文件为float的时候,如果有缺失,就会出现nan

  • 当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)

inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷

什么时候回出现inf包括(-inf,+inf)

  • 比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf

注意他们的type类型:

# NAN的赋值为a=np.nanIn [82]: a = np.nanIn [83]: type(a)
Out[83]: floatIn [84]: b = np.infIn [85]: type(b)
Out[85]: float

numpy中的nan的注意点:

  • 两个nan是不相等的

  • In [87]: np.nan==np.nan
    Out[87]: False

  • np.nan!=np.nan

  • In [88]: np.nan!=np.nan
    Out[88]: True

  • 利用以上的特性判断数组中nan的个数

  • In [89]: t
    Out[89]:
    array([[ 0., 1., 2., 3., 4., 5.],
    [ 6., 7., 8., 9., 10., 11.],
    [12., 13., 14., 15., 16., 17.],
    [18., 19., 20., nan, nan, nan]])

    In [90]: np.count_nonzero(t!=t)
    Out[90]: 3

  • 可以通过np.isnan(a)来判断a数组中是否具有nan,返回bool类型,比如希望把nan替换为0

  • In [92]: np.isnan(t)
    Out[92]:
    array([[False, False, False, False, False, False],
    [False, False, False, False, False, False],
    [False, False, False, False, False, False],
    [False, False, False, True, True, True]])

    In [93]: t[np.isnan(t)]=0

    In [94]: t
    Out[94]:
    array([[ 0., 1., 2., 3., 4., 5.],
    [ 6., 7., 8., 9., 10., 11.],
    [12., 13., 14., 15., 16., 17.],
    [18., 19., 20., 0., 0., 0.]])

  • nan和任何值计算都为nan

在一组数据中单纯的把nan替换为0,是一种不可取的方式。比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行。

ndarry缺失值填充均值

import numpy as npt = np.array([[0., 1., 2., 3., 4., 5.],[6., 7., np.nan, 9., 10., 11.],[12., 13., 14., np.nan, 16., 17.],[18., 19., 20., 21., 22., 23.]])
print(t)def fill_nan_by_column_mean(t):for i in range(t.shape[1]):  # t.shape[1]返回列的个数nan_num = np.count_nonzero(t[:, i] != t[:, i])  # 返回nan的个数if nan_num > 0:now_col = t[:, i]# 对非nan的元素求和now_col_not_nan = now_col[np.isnan(now_col) == False].sum()# 求列平均值now_col_mean = now_col_not_nan / (t.shape[0] - nan_num)# 赋值给now_colnow_col[np.isnan(now_col)] = now_col_mean# 赋值给t,即更新t的当前列t[:, i] = now_colfill_nan_by_column_mean(t)
print(t)
'''
[[ 0.  1.  2.  3.  4.  5.][ 6.  7. nan  9. 10. 11.][12. 13. 14. nan 16. 17.][18. 19. 20. 21. 22. 23.]]
[[ 0.  1.  2.  3.  4.  5.][ 6.  7. 12.  9. 10. 11.][12. 13. 14. 11. 16. 17.][18. 19. 20. 21. 22. 23.]]
'''

numpy生成随机数

数据分析matplotlibnumpy相关推荐

  1. Velodyne VLP-16激光雷达数据分析

    Velodyne VLP-16激光雷达数据分析 Velodyne VLP-16激光雷达保持了 Velodyne 在 LiDAR 中的突破性重要功能:实时收发数据.360 度全覆盖.3D 距离测量以及校 ...

  2. 2021年大数据Spark(五十一):Structured Streaming 物联网设备数据分析

    目录 ​​​​​​​物联网设备数据分析 ​​​​​​​设备监控数据准备 ​​​​​​​创建Topic ​​​​​​​模拟数据 ​​​​​​​SQL风格 ​​​​​​​DSL风格 物联网设备数据分析 在 ...

  3. 2021年大数据Spark(二十八):SparkSQL案例三电影评分数据分析

    目录 案例三:电影评分数据分析 代码实现 Shuffle分区数 案例三:电影评分数据分析 使用电影评分数据进行数据分析,分别使用DSL编程和SQL编程,熟悉数据处理函数及SQL使用,业务需求说明: 对 ...

  4. Excel的数据分析—排位与百分比

    Excel的数据分析-排位与百分比 某班级期中考试进行后,按照要求仅公布成绩,但学生及家长要求知道排名.故欲公布成绩排名,学生可以通过成绩查询到自己的排名,并同时得到该成绩位于班级百分比排名(即该同学 ...

  5. python 面板数据分析_科学网—Python中的结构化数据分析利器-Pandas简介 - 郑俊娟的博文...

    此文转载于XXXXXX处... Pandas是python的一个数据分析包,最初由AQR Capital Management于2008年4月开发,并于2009年底开源出来,目前由专注于Python数 ...

  6. ESI计算机排名2021年01月,喜忧参半!2021年5月ESI世界大学排行榜,21个学科排名数据分析!...

    原标题:喜忧参半!2021年5月ESI世界大学排行榜,21个学科排名数据分析! 2021年5月13日,科睿唯安发布了<2021年5月ESI中国高校排行榜>. 一.计算机科学专业 1.清华大 ...

  7. python数据分析要学什么_python数据分析学什么?python数据分析入门

    有很多没有基础的新手想学习python数据分析,却在纠结python数据分析难不难学?下面万古网校小编给大家整理了资料,为各位分享! 1.python难不难? Python可以说是目前比较主流而且易学 ...

  8. python数据分析实训大纲,数据分析大赛考纲:(二)Python数据分析应会部分

    1.1. Numpy库的使用 1.1.1. Numpy数组的创建 1. 了解Numpy中ndarray数组对象的性质和特点: 1. 掌握通过array()函数创建Numpy数组的方法,会将Python ...

  9. v-model无法对返回的数据进行填写_学会数据分析思维,学会透过事物看本质

    这段时间通过学习相关的知识,最大的变化就是看待事物更加喜欢去了解事物后面的本质,碰到问题后解决问题思路也发生了改变. 举个具体的例子,我在学习数据分析,将来会考虑从事这方面的工作,需要掌握的相关专业知 ...

最新文章

  1. Django----缓存
  2. 基于 flyweight 的格式化文本处理的 Boost.Flyweight 示例
  3. dell c6220II lsi阵列卡
  4. 乘法口诀表的C语言编程
  5. 消息测试服务器,测试统一消息服务器功能
  6. Linux NGINX 主备,使用keepalived实现主备(以nginx为例)
  7. Java中File操作
  8. win11系统联想电脑怎么安装 Windows11系统联想电脑安装步骤
  9. 机器学习 python 库_Python机器学习库
  10. 电子邮件是html文件吗,如何在电子邮件正文中嵌入HTML文件
  11. ApiPost、Postman及并发测试工具Jmeter、PostJson接口测试工具,设置参数传递。
  12. 城八区和通州区限价房申请5月16日开始受理
  13. Excel2003和Excel2007对下拉选择和下拉级联选择的操作以及java程序的调用
  14. opengl绘制太阳、地球、月亮,贴上纹理,设置光照,符合自转和公转规律
  15. c#实现爬虫获取小说(.NET)
  16. 水上运动装备的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  17. 一路编程,一路迷茫,一路醒悟,接着迷茫,再醒悟再迷茫
  18. hdu 2121 最小树形图 +虚根
  19. 中国市场杂志社中国市场编辑部2022年第32期目录
  20. 单片机与PC机的交流———基于STM32的串口通信

热门文章

  1. 【SpringBoot】〖自定义〗SpringBoot十二星座启动图标
  2. APP开发的首要问题:如何找到一家专业的APP开发公司?
  3. RuntimeError: 0D or 1D target tensor expected, multi-target not supported解决
  4. 04-0001 Matlab新手指导
  5. vue form表单验证
  6. 微信小程序bindtap和carchtap的区别
  7. paddlepaddle简单的黑白边界检测
  8. 杂记:三、mybatis中常见 Java 类型的内置类型别名
  9. Arduino简单实例之四_PS2游戏摇杆
  10. shuf 随机选取txt文件特定行数