[NumPy]入门-学习笔记
2016-04-06 05:47
791 查看
[NumPy]入门-学习笔记
实习是关于机器学习的一个项目,博主渣硕之前只有学过Python的基础,没有Python方面的项目经历。鉴于目前Python在机器学习方面的火爆,以及对Python未来的看好。决定用Python来,希望能够完成实习任务。推荐一个很好的Data Science方向在线学习网站DATAQUEST。该网站部分免费,免费部分也很有意思,思路非常清晰。本文只介绍NumPy的常用的基本操作。数据集
本来想自己敲代码,演示下。但是原文的数据集: world_alcohol.csv 我没有找到,所以我只能“翻译”原文了。教程中的数据如下表所示(后续的联系都是基于这个数据集):Year | Region | Country | Beverage Types | Display Value |
---|---|---|---|---|
1986 | ‘Western Pacific’ | ‘Viet Nam’ | ‘Wine’ | 0 |
1986 | ‘Americas’ | ‘Uruguay’ | ‘Other’ | 0.5 |
1985 | ‘Africa’ | ‘Cte d’Ivoire’ | ‘Wine’ | 1.62 |
Year: 调查年份
Region: 国家所在地区
Country: 国家
Beverage Types: 饮品类别
Display Value: 该国公民该类饮品平均消费量,单位升
列表的列表 (list of lists)
列表的列表,其实就是矩阵 (Matrix)。原生的Python就支持此操作。在介绍NumPy之前,先介绍Python原生操作。这样方便对比两者之间的优劣。world_alcohol.csv 中的数据是表格的形式存在的,其实就是矩阵啦。下面是数据集中的几个数据展示。
world_alcohol = [ [1986, "Western Pacific", "Viet Nam", "Wine", 0], [1986, "Americas", "Uruguay", "Other", 0.5], [1986, "Africa", "Cte d'Ivoire", "Wine", 1.62] ]
我们能用list的操作来得到第一行数据:
first_row = world_alcohol[0]
first_row 的内容是:
[1986, "Western Pacific", "Viet Nam", "Wine", 0]
first_row[0] 能得到1986, first_row[1]能得到Wine。第一个index取得相应的行,第二个index取得相应的列。行列号都是从0开始的。比如world_alcohol[1][1]能德高‘Americas’。
原生Python中不方便的地方是计算统计值。比如我们想计算Display Value的平均值,我们必须要循环遍历数组,如下:
>>> liters_drank = [] >>> for row in world_alcohol: ... liters_drank.append(row[4]) >>> liters_drank = liters_drank[1:len(liters_drank)] >>> total = 0 >>> for item in liters_drank: ... total = total + float(item) >>> print(sum(liters_drank) / len(liters_drank))
我们可以看到,用原生list计算数据统计数值的时候,需要遍历list,这样很不方便。NumPy引入了对矩阵的统计方法。
NumPy
Numpy比Python原生的数组,矩阵操作高效多了。Numpy是Python用来操作多维数组的一个模块。它效率更高,提供的接口方法更多。创建方法
直接用array()方法创建>>> import numpy >>> >>> vector = numpy.array([5, 10, 15, 20])
引用 .csv文件, genfromtext(filename, dtype, delimiter…). 需要注意的是NumPy只能是同一种数据类型,关于数据类型,下文中会讲到。
>>> import numpy >>> >>> world_alcohol = numpy.genfromtext('world_alcohol.csv', delimiter = ',' =)
数据类型
可以用dtype属性来查看数据类型,一个NumPy数组只支持一种数据类型。NumPy可支持的数据类型有:bool: 布尔型, True 或者False
int: 整型,其中有 int16, int32, 和 int64类型。后缀16, 32, 和 64 表示数据长度。
float:浮点数。同样有float16, float32, 和 float64。后缀16, 32, 和 64 表示数据长度,长度越长,数据准确度越高。
string:字符串。
读取world_alcohol.csv会发现,里面有数据类型na (Not Available)和nan (Not A Number),前者表示读取的数值是空的,是不存在的。后者是因为数据类型转换出错。
>>> numbers = numpy.array([1, 2, 3, 4]) >>> print(numbers.dtype) int64 # the datatype is int64
Array Shape
通过shape属性能够查看array的大小, 或者通过shape()方法查看>>> vector1 = numpy.array([1, 2, 3, 4]) >>> # use shape property to print >>> print(vector1.shape) 4 >>> vector2 = numpy.array([[1, 2, 3], [4, 5, 6]]) >>> # use shape() method to print >>> print(numpy.shape(vector2)) (2, 3)
正确读取数据
我们在数据类型这段提到过nan错误,我们可以用genfromtxt()来转化数据类型。对于world_alcohol.csv我们可以这样做:dtype关键字要设定为‘U75’. 表示每个值都是75byte的 unicode。
skip_header关键字设为 True, 这个参数能让跳过表格第一行,可就是关于列信息那行。
>>> import numpy >>> import csv >>> world_alcohol_csv = csv.reader(open('world_alcohol.csv')) >>> world_alcohol = numpy.genfromtxt('world_alcohol.csv', dtype='U75', delimiter=',', skip_head=True)
Indexing Arrays
NumPy支持list一样的定位操作。>>> matrix = numpy.array([ ... [5, 10, 15], ... [20, 25, 30] ... ]) >>> print(matrix[1, 2]) 30
切片(Slicing)
NumPy支持list一样的切片操作。>>> matrix = numpy.array([ ... [5, 10, 15], ... [20, 25, 30], ... [35, 40, 45] ... ]) >>> print(matrix[:1]) [[ 5 10 15]] >>> print(matrix[:,1]) [10 25 40] >>> print(matrix[1:3, 0:2]) [[20 25] [35 40]]
数组比较
NumPy最强大的地方是数组的比较。数组比较会产生boolean值。对数组的比较:
>>> vector = numpy.array([1, 2, 3, 4]) >>> vector == 1 array([ True, False, False, False], dtype=bool)
对矩阵的比较:
>>> matrix = numpy.array([ ... [5, 10, 15], ... [20, 25, 30], ... [35, 40, 45] ... ]) >>> matrix == 25 array([[False, False, False], [False, True, False], [False, False, False]], dtype=bool)
现在我们做一个练习,在world_alcohol.csv中:
获取国家是否是Canada的数组
获取年份是否是1984的数组
>>> import numpy >>> >>> # 重新演示如何从csv文件中生成矩阵 >>> world_alcohol = numpy.genfromtxt('world_alcohol.csv', dtype='U75', delimiter=',', skip_header=True) >>> >>> countries_canada = (world_alcohol[:, 2] == 'Canada') >>> years_1984 = (world_alcohol[:, 0] == '1984')
选择元素
现在我们要体验一下为什么数组比较是这么强大。我们可以用数组比较得到的布尔值来条件取值。在数组中:
>>> vector = numpy.array([5, 10, 15, 20]) >>> print(vector) [ 5 10 15 20] >>> equal_to_ten = (vector == 10) >>> print(equal_to_ten) [False True False False] >>> # 输出只有相对于位布尔值是True位置上的值 >>> print(vector[equal_to_ten]) [10]
在矩阵中:
>>> matrix = numpy.array([ ... [5, 10, 15], ... [20, 25, 30], ... [35, 40, 45] ... ]) >>> second_column_25 = (matrix[:,1] == 25) >>> print(second_column_25) [False True False] >>> print(matrix[second_column_25, :]) [[20 25 30]] >>>
在这段代码中:
我们先创立数组matrix
将matrix的第二列和25比较,得到一个布尔值数组second_column_25
在matrix中,选择second_column_25是True的行
现在做一个小练习,在world_alcohol中获取国家是Algeria(阿尔及利亚)的数据:
>>> country_is_algeria = world_alcohol[:, 2] == 'Algeria' >>> country_algeria = world_alcohol[country_is_algeria, :]
我们没有world_alcohol.csv的数据集,我贴一份从DATAQUEST上得到的运行结果吧
ndarray (<class 'numpy.ndarray'>) array([['1984', 'Africa', 'Algeria', 'Spirits', '0.01'], ['1987', 'Africa', 'Algeria', 'Beer', '0.17'], ['1987', 'Africa', 'Algeria', 'Spirits', '0.01'], ['1986', 'Africa', 'Algeria', 'Wine', '0.1'], ['1984', 'Africa', 'Algeria', 'Other', '0'], ['1989', 'Africa', 'Algeria', 'Beer', '0.16'], ['1989', 'Africa', 'Algeria', 'Spirits', '0.01'], ['1989', 'Africa', 'Algeria', 'Wine', '0.23'], ['1986', 'Africa', 'Algeria', 'Spirits', '0.01'], ['1984', 'Africa', 'Algeria', 'Wine', '0.12'], ['1985', 'Africa', 'Algeria', 'Beer', '0.19'], ['1985', 'Africa', 'Algeria', 'Other', '0'], ['1986', 'Africa', 'Algeria', 'Beer', '0.18'], ['1985', 'Africa', 'Algeria', 'Wine', '0.11'], ['1986', 'Africa', 'Algeria', 'Other', '0'], ['1989', 'Africa', 'Algeria', 'Other', '0'], ['1987', 'Africa', 'Algeria', 'Other', '0'], ['1984', 'Africa', 'Algeria', 'Beer', '0.2'], ['1985', 'Africa', 'Algeria', 'Spirits', '0.01'], ['1987', 'Africa', 'Algeria', 'Wine', '0.1']], dtype='<U75')
替代值(Replacing Value)
NumPy可以运用布尔值来替换值。在数组中:
>>> vector = numpy.array([5, 10, 15, 20]) >>> equal_to_ten_or_five = (vector == 10) | (vector == 5) >>> vector[equal_to_ten_or_five] = 50 >>> print(vector) [50, 50, 15, 20]
在矩阵中:
>>> matrix = numpy.array([ ... [5, 10, 15], ... [20, 25, 30], ... [35, 40, 45] ... ]) >>> second_column_25 = matrix[:,1] == 25 >>> matrix[second_column_25, 1] = 10 >>>> print(matrix) [[ 5 10 15] [20 10 30] [35 40 45]]
在这段代码中:
我们先创立数组matrix
将matrix的第二列和25比较,得到一个布尔值数组second_column_25
将matrix第二列值为25的替换为10
惯例,我们做一个小练习。将world_alcohol年份为1986的行替换成年份2014。
world_alcohol[world_alcohol[:, 0] == '1986', 0] = 2014 world_alcohol[world_alcohol[:, 3] == 'Wine', 3] = 'Grog'
偷个懒,数据就不粘上来了。
替换有一个很棒的应用之处,就是替换那些空值。之前提到过NumPy中只能有一个数据类型。刚才我们把所有的world_alcohol.csv中的值按String读取。所以原来的整形都被自动转换成String了。其中的空值我们很有必要把他们替换成其他值,比如数据的平均值或者把他们删除。这在大数据处理中很有必要。这里,我们演示把Display value中空值替换为0的操作。
>>> is_value_empty = world_alcohol[:, 4] == '' >>> world_alcohol[is_value_empty, 4] = '0'
数据类型转换
我们能用astype()方法来转换数据类型。比如,把String转换成float。如下:
>>> vector = numpy.array(["1", "2", "3"]) >>> vector = vector.astype(float)
小练习,把world_alcohol.csv中Display value从String转换成Float:
>>> alcohol_consumption = world_alcohol[:, 4] >>> alcohol_consumption = alcohol_consumption.astype(float)
NumPy的统计计算方法
NumPy内置很多计算方法。其中最重要的统计方法有:sum():计算数组元素的和;对于矩阵计算结果为一个一维数组,需要指定行或者列
mean():计算数组元素的平均值;对于矩阵计算结果为一个一维数组,需要指定行或者列
max():计算数组元素的最大值;对于矩阵计算结果为一个一维数组,需要指定行或者列
需要注意的是,用于这些统计方法计算的数值类型必须是int或者float。
数组例子:
>>> vector = numpy.array([5, 10, 15, 20]) >>> vector.sum() 50
矩阵例子:
>>> matrix array([[ 5, 10, 15], [20, 10, 30], [35, 40, 45]]) >>> matrix.sum(axis=1) array([ 30, 60, 120]) >>> matrix.sum(axis=0) array([60, 60, 90])
有例子所示,axis = 1计算的是行的和,结果以列的形式展示。axis = 0计算的是列的和,结果以行的形式展示。
练习
NumPy的基本操作介绍得差不多了,现在需要的就是练习啦。Ex1:计算Canada 1986年的饮品消费总量。
>>> is_canada_1986 = (world_alcohol[:, 0] == '1986') & (world_alcohol[:, 2] == 'Canada') >>> canada_1986 = world_alcohol[is_canada_1986, :] >>> canada_1986[canada_1986[:, 4] == '', 4] = '0' >>> canada_alcohol = canada_1986[:, 4] >>> canada_alcohol = canada_alcohol.astype(float) >>> total_canadian_drinking = canada_alcohol.sum()
解题方法很直接。基本思路就是先选出国家是Canada,年份是1986的数组。然后在调用NumPy内置的素描()方法。
Ex2:计算每个国家的饮品消费总量。
>>> totals = {} >>> countries = world)alcohol[:2] >>> >>> for country in countries: ... is_country_1989 = (world_alcohol[:, 0] == '1989') & (world_alcohol[:, 2] == country) ... country_consumption = world_alcohol[is_country_1989, :] ... country_consumption[country_consumption[:, 4] == '', 4] = '0' ... country_alcohol = country_consumption[:, 4].astype(float) ... totals[country] = country_alcohol.sum()
Ex3:计算饮品消费总量最多的国家。
>>> highest_value = 0 >>> highest_key = None >>> >>>for key in totals.keys(): ... if totals[key] > highest_value: ... highest_value = totals[key] ... highest_key = key
NumPy的优缺点
通过上面基本介绍和给出的列子,我们发现NumPy比list of lists更方便:更简单地数值统计计算
indexing和slicing更快更简单
数值类型更容易转换
NumPy多数据的处理更快更高效,所以应用很广泛。特别是在机器学习方面。
同时,我们也注意到了NumPy的不足之处:
整个列表需要有相同的数据类型,这对于有些数据集来说很不方便
行列只能用数值来选取,来表示。不能通过列的名称去定位列
很幸运,前辈们已经注意到NumPy的不足之处。Pandas库很好的弥补了NumPy的缺点。下面,要开始学习Pandas了。
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- 我是运营,我没有假期
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例