集智专栏
资源加载中,请稍后...
集智专栏

[2018.03.21直播] Python数值计算:NumPy(I)

Kaiser

往期回顾

负基础入门Python系列汇总


直播时间 21:00

1. 页内观看(仅视频)

2. 完整观看(可发弹幕):Python数值计算:NumPy

3. Bilibili直播



26. NumPy

26.1 嵌套列表表示:

程序说明
嵌套列表表示
示例代码
arr_lst = [[1,2,3,4], [12,13,14,5], [11,16,15,6], [10,9,8,7]] arr_lst


程序说明
访问元素
预处理代码
arr_lst = [[1,2,3,4], [12,13,14,5], [11,16,15,6], [10,9,8,7]]
示例代码
# 首行 print(arr_lst[1]) # 2行3列 print(arr_lst[2][3])


程序说明
最后一列
预处理代码
arr_lst = [[1,2,3,4], [12,13,14,5], [11,16,15,6], [10,9,8,7]]
示例代码
[i[len(arr_lst[0])-1] for i in arr_lst]


26.2 嵌套列表计算

程序说明
Computations
示例代码
# 所有元素 -1 arr_lst - 1 # 所有元素*2 # arr_lst * 2 # 大于9的元素 # arr_lst > 9


26.3 NumPy ndarray

程序说明
ndarray
示例代码
import numpy as np arr_lst = [[1,2,3,4], [12,13,14,5], [11,16,15,6], [10,9,8,7]] arr = np.array(arr_lst) print('arr -> ', arr) print('\ntype(arr) -> ', type(arr))


27. NumPy常用方法

27.1 shape

程序说明
np.shape
示例代码
arr = np.array([[ 1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]) print('arr.shape -> ', arr.shape) print('\ntype(arr.shape) -> ', type(arr.shape))


程序说明
ndarray.reshape
示例代码
arr = np.array([[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]) arr.reshape(2,8)


27.2 基本运算

程序说明
ndarray computations
示例代码
print('arr - 1 -> \n', arr-1) print('\narr * 2 -> \n', arr * 2) print('\narr > 9 -> \n', arr > 9)


27.3 数据类型

程序说明
dtype
示例代码
str_lst = [[0, "zero"], [1, "one"], [2, "two"], [3, "three"]] print('str_lst - > \n', str_lst) str_arr = np.array(str_lst) print('str_arr.dtype -> \n', str_arr.dtype) #str_arr + 1 #str_arr * 2 #str_arr > 9


程序说明
异性矩阵
示例代码
import numpy as np arr_lst1 = [[2,3,4], [12,13,14,5], [11,16,15,6], [10,9,8,7]] arr1 = np.array(arr_lst1) arr1.shape


更多NumPy操作可提前自学NumPy官方教程,之后的直播会以习题案例形式讲解。



Quiz 29:上过的舰加起来有七八十艘吧

BattleshipBattleship

BattleshipBattleship


Battleship是一个海战桌游,现在也有网络版:http://zh.battleship-game.org

现在你是一名提督,需要编写一段程序来模拟打炮过程,棋盘用2维矩阵表示:

4 0 0 2 2 2 2
3 0 3 0 0 0 0
2 0 3 0 1 0 0
1 0 3 0 1 0 0
0 1 2 3 4 5 6

其中首列、末行表示坐标轴,0表示海面,数字表示船体。如上图,牌面上共有3艘船,大小(长度)分别是2,3,4。

之后会受到多个点的攻击,着弹点坐标也表示为2维矩阵,那么本回合就表示为:

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

attacks = [[2, 1], 
           [1, 3], 
           [4, 2]]

船体的每个单元受攻击后损毁(中破),如果一艘船的所有单元都被攻击则该船沉没(大破)。


我们需要定义的函数battle()输入参数为舰队board和攻击attacks两个列表,需要输出的是战损统计情况,以字典形式表示。比如上面例子中的攻击过后,1号和3号船各受一次攻击,但都未沉没,2号船没有中枪,则统计结果为:

{'sunk':0,
 'damaged':2,
 'intact':1}


为了做好一名提督,请完成以下函数定义:

程序说明
BattleShip
示例代码
import numpy as np def battle(board, attacks): # 从题示坐标到NumPy Array的坐标变换 attacks_arr = np.array(attacks) - 1 board_arr = np.array(board) board_arr = board_arr.T[:,::-1] # >>>> keep calm and show me the code <<<< # >>>> keep calm and show me the code <<<<
正确答案
import numpy as np def battle(board, attacks): attacks_arr = np.array(attacks) - 1 board_arr = np.array(board) board_arr = board_arr.T[:,::-1] def ship_counts(board_arr): board_lst = list(board_arr.reshape(board_arr.shape[0] * board_arr.shape[1])) ships = {i:board_lst.count(i) for i in board_lst} del ships[0] return ships ships = ship_counts(board_arr) board_tf = board_arr > 0 for i in zip(attacks_arr[:,0], attacks_arr[:,1]): if board_tf[i] == True: board_tf[i] = False board_atk = board_arr * board_tf ships_atk = ship_counts(board_atk) def ship_stats(ships, ships_atk): sunk = 0 damaged = 0 intact = 0 # points = 0 for i in ships: if i not in ships_atk: sunk += 1 elif ships_atk[i] < ships[i]: damaged += 1 elif ships_atk[i] == ships[i]: intact += 1 return {'sunk': sunk, 'damaged':damaged, 'intact':intact} return ship_stats(ships, ships_atk)
程序验证过程
board0 = [[1,1,1],[0,0,0],[0,2,0], [0,2,0]] attacks0 = [[1, 4], [2, 4], [ 3, 4]] solu0 = { 'sunk': 1, 'damaged': 0 , 'intact': 1 } board1 = [[0,0,1],[0,0,1],[0,2,0], [0,2,0]] attacks1 = [[3, 4],[2, 1],[ 2, 2]] solu1 = {'sunk': 1, 'damaged': 1 , 'intact': 0} def answer_check(): flag = True if battle(board0, attacks0)['damaged'] != solu0['damaged']: flag = False if battle(board0, attacks0)['sunk'] != solu0['sunk']: flag = False if battle(board0, attacks0)['intact'] != solu0['intact']: flag = False if battle(board1, attacks1)['damaged'] != solu1['damaged']: flag = False if battle(board1, attacks1)['sunk'] != solu1['sunk']: flag = False if battle(board1, attacks1)['intact'] != solu1['intact']: flag = False return flag answer_check()
提示信息
注意 numpy 处理数组的方式

您也许喜欢这些文章

集智专栏

[2018.05.08直播] Python之面向对象

发表至系列教程
2018年5月8日直播配套专栏,介绍Python的面向对象特性,并参照TensorFlow的计算图机制,尝试手动“山寨”一套深度学习框架。
集智专栏

[Scikit-learn教程] 01 快速入门

发表至系列教程
从本篇文章开始,我们将在一系列的文章中介绍使用scikit-learn——一个著名的机器学习库件来完成机器学习过程的各种方法,包括算法的选择、模型的构建与训练、训练结果的评估等等。同时提供丰富的案例与小测试,帮助读者深刻掌握机器学习与数据挖掘领域中的各类基础知识与技能。
集智专栏

[Scikit-learn教程] 02.04 无监督学习:追寻数据表征

发表至系列教程
此前所有的算法,不论回归(Regression)还是分类(Classification),都是根据已知标签训练模型再应用到新数据上。而如果一开始就没有标签可供参考呢?就需要用到新的机器学习方法:聚类(Clustering)。

文章评论(7)

新用户374 发表于 1月前回复
回复Kaiser:因为Python Array里的坐标原点是“左上角”,而咱们平时理解的原点是左下角。
拜谢大神,我还得好好消化下
Kaiser集智 站长 发表于 2月前回复
回复新用户374:board_arr = board_arr.T[:,::-1] 这步的操作还是不太明白是有什么作用?
因为Python Array里的坐标原点是“左上角”,而咱们平时理解的原点是左下角。
Kaiser集智 站长 发表于 2月前回复
回复新用户374:board_arr = board_arr.T[:,::-1] 这步的操作还是不太明白是有什么作用?
这一步其实就是一个旋转,.T是行列转置,[:,::-1]是行不变,列倒序。
新用户374 发表于 2月前回复
board_arr = board_arr.T[:,::-1] 这步的操作还是不太明白是有什么作用?
Kaiser集智 站长 发表于 3月前回复
回复联机之渣:K神,这期视频不全吧,前面少一大段
想起来了,这次直播有点卡顿,前面一段是在调试,我掐掉了
Kaiser集智 站长 发表于 3月前回复
回复联机之渣:K神,这期视频不全吧,前面少一大段
可能是直播平台的问题,我看一下
联机之渣 发表于 3月前回复
K神,这期视频不全吧,前面少一大段