本文由 沈庆阳 所有,转载请与作者取得联系!
引言
在上一讲中,我们了解了机器学习程序中的数据集发挥着极为重要的作用。可以说,没有良好的数据集就无法得到合适的模型。但是准备数据集是一项极其枯燥乏味,且需要大量时间的工作。那么在学习和练习的过程中,有没有简单有效且迅速的方法来获取数据集呢?
答案是肯定的。现如今机器学习的社区日渐庞大,对于各种机器学习问题的数据集也越来越多。像我们前面提到的Microsoft维护的COCO数据集就是在目标检测上面的一个例子。对于一些数据格式来说,我们需要用数据分析的工具来讲现有的数据提取为我们需要的数据。对于列存数据的分析,我们使用Pandas API来进行。
Pandas是用于处理和分析输入数据的工具,目前很多机器学习的框架都支持使用Pandas数据结构作为输入。
安装Pandas很简单,通过pip install pandas命令即可完成对pandas的安装。
导入pandas,并输出相应的版本号。
import pandas as pd
pd.__version__
Pandas API的基本概念
创建Series和DataFrame对象
在进行如下学习的过程中,建议在Python Shell、或是Python控制台运行,因为可以直观地看到运行的结果,而不是需要print函数进行输出。
Pandas中的数据结构有如下两类:
1、DataFrame:由多个行和有名称的列构成的关系型数据表格。
2、Series:单一的列。每个Series均有一个名称,且一个DataFrame中包含一个或多个Series。
DataFrame是用于数据操控的一种常见的抽象实现形式。
通过如下代码可以创建Series:
pd.Series(['San Francisco', 'San Jose', 'Sacramento'])
控制台输出如下
0 San Francisco
1 San Jose
2 Sacramento
dtype: object
可以看到,我们定义了一列由CA的几个区名构成的一个Series(列)。
由一个或多个列组成一个DataFrame的例子如下:
city_names = pd.Series(['San Francisco', 'San Jose', 'Sacramento'])
population = pd.Series([852469, 1015785, 485199])
pd.DataFrame({ 'City name': city_names, 'Population': population })
首先,定义了city_names和population两个Series对象,并通过Pandas的DataFrame构造函数构造了一个新的DataFrame。在构造DataFrame的时候,为其每个Series指定了名称。
在DataFrame的构造函数中,其用法与Dictionary的用法较为类似。
在构造DataFrame的时候,如果两个Series的长度不一致,如一个Series有3行,一个Series有2行,那么构造的DataFrame较短的Series的第三行则为NA/Nan值来填充。
上述构建DataFrame的结果如下:
City name Population
0 San Francisco 852469
1 San Jose 1015785
2 Sacramento 485199
从网络读取数据与DataFrame的基本操作
大多数情况下,我们可以通过网络来读取数据,并创建特征定义。在Pandas中,可以使用pd.read_csv()函数来读取csv文件,并由此创建DataFrame对象。
以加利福尼亚的房价数据为例(california_housing_train.csv),文件存储位置(https://raw.githubusercontent.com/sqy941013/learnmachinelearning/master/california_housing_train.csv)
california_housing_dataframe = pd.read_csv("https://raw.githubusercontent.com/sqy941013/learnmachinelearning/master/california_housing_train.csv", sep=",")
california_housing_dataframe.describe()
其通过pandas的DataFrame对象的describe()函数输出关于该的DataFrame的内容的一些统计信息如下:
longitude latitude housing_median_age total_rooms \
count 17000.000000 17000.000000 17000.000000 17000.000000
mean -119.562108 35.625225 28.589353 2643.664412
std 2.005166 2.137340 12.586937 2179.947071
min -124.350000 32.540000 1.000000 2.000000
25% -121.790000 33.930000 18.000000 1462.000000
50% -118.490000 34.250000 29.000000 2127.000000
75% -118.000000 37.720000 37.000000 3151.250000
max -114.310000 41.950000 52.000000 37937.000000
total_bedrooms population households median_income \
count 17000.000000 17000.000000 17000.000000 17000.000000
mean 539.410824 1429.573941 501.221941 3.883578
std 421.499452 1147.852959 384.520841 1.908157
min 1.000000 3.000000 1.000000 0.499900
25% 297.000000 790.000000 282.000000 2.566375
50% 434.000000 1167.000000 409.000000 3.544600
75% 648.250000 1721.000000 605.250000 4.767000
max 6445.000000 35682.000000 6082.000000 15.000100
median_house_value
count 17000.000000
mean 207300.912353
std 115983.764387
min 14999.000000
25% 119400.000000
50% 180400.000000
75% 265000.000000
max 500001.000000
可以看到,我们的csv文件有经纬度、房屋年龄、总房间数等Series。而describe()函数统计了这些Series的总数(count)、平均数(mean)、最小值(min)等统计学中的信息。
与DataFrame有关的另一个比较有用的函数是head()。通过head()函数可以显示DataFrame的前几个记录
california_housing_dataframe.head()
longitude latitude housing_median_age total_rooms total_bedrooms \
0 -114.31 34.19 15.0 5612.0 1283.0
1 -114.47 34.40 19.0 7650.0 1901.0
2 -114.56 33.69 17.0 720.0 174.0
3 -114.57 33.64 14.0 1501.0 337.0
4 -114.57 33.57 20.0 1454.0 326.0
population households median_income median_house_value
0 1015.0 472.0 1.4936 66900.0
1 1129.0 463.0 1.8200 80100.0
2 333.0 117.0 1.6509 85700.0
3 515.0 226.0 3.1917 73400.0
4 624.0 262.0 1.9250 65500.0
此外,Pandas还可以绘制图表。例如DataFrame的Hist函数,我们可以快速地绘制出一个列中值的分布(需要安装matplotlib)。
california_housing_dataframe.hist('housing_median_age')
使用如下命令显示上图
from pylab import *
show()
Hist函数绘制的统计图
使用Pandas访问数据
访问Pandas的数据结构中的数据(DataFrame与Series)可以使用Python语言中访问Dictionary与List的语法来访问。
首先创建一个名为cities的DataFrame,然后输出cities中的city_names的所有数据:
cities = pd.DataFrame({ 'City name': city_names, 'Population': population })
print type(cities['City name'])
cities['City name']
运行结果:
<class 'pandas.core.series.Series'>
0 San Francisco
1 San Jose
2 Sacramento
Name: City name, dtype: object
或访问city_names的第2个数据:
print type(cities['City name'][1])
cities['City name'][1]
运行结果:
<type 'str'>
'San Jose'
或是输出第1到第2个数据:
print type(cities[0:2])
cities[0:2]
运行结果:
City name Population
0 San Francisco 852469
1 San Jose 1015785
关于Pandas的高级索引和选择功能,参见官方API文档:http://pandas.pydata.org/pandas-docs/stable/indexing.html
Pandas中操控数据
对Pandas中的数据结构的操作可以使用Python的基本运算指令。如:
population / 1000
得到:
0 852.469
1 1015.785
2 485.199
dtype: float64
还可以使用Numpy科学计算工具包进行计算,Pandas中的Series可以作为大部分Numpy函数的参数:
使用import numpy as np
导入Numpy包。通过np.log(population)
来进行控制台输出(以log函数为例)。
>>> import numpy as np
>>> np.log(population)
0 13.655892
1 13.831172
2 13.092314
dtype: float64
对于单列转换,可以使用Series.apply函数来进行。
与Python的映射函数类似,Series.apply()接收lambda函数,并且lambda函数运用于每个值。
以创建population是否超过100万的Series为例:
population.apply(lambda val: val > 1000000)
0 False
1 True
2 False
dtype: bool
从apply函数中,我们创建了一个新的Series,其存储的是population在该行是否人口大于100万。
对DataFrame的修改也很简单。我们可以对DataFrame进行添加新的Series。
>>> cities['Area square miles'] = pd.Series([46.87, 176.53, 97.92])
>>> cities['Population density'] = cities['Population'] / cities['Area square miles']
>>> cities
City name Population Area square miles Population density
0 San Francisco 852469 46.87 18187.945381
1 San Jose 1015785 176.53 5754.177760
2 Sacramento 485199 97.92 4955.055147
索引
Series和DataFrame也定义了index属性,其index属性会向每个Series或DataFrame行赋一个标识符。
初始情况下,构造Series或DataFrame时,Pandas会付给标识符反映原始数据顺序的索引值。一般来说,索引值在Series或DataFrame对象创建完成之后是稳定的。其不会根据数据的重新排序而发生改变。
>>> city_names.index
RangeIndex(start=0, stop=3, step=1)
>>> cities.index
RangeIndex(start=0, stop=3, step=1)
通过调用DataFrame的reindex()函数来进行各行的重新排序。
City name Population Area square miles Population density Is wide and has saint name
2 Sacramento 485199 97.92 4955.055147 False
0 San Francisco 852469 46.87 18187.945381 False
1 San Jose 1015785 176.53 5754.177760 True
通过reindex()函数,我们可以对DataFrame进行打乱顺序重新排序(随机排序)。reindex()函数也可以和Numpy的random.permutation()函数相结合。
cities.reindex(np.random.permutation(cities.index))
City name Population Area square miles Population density Is wide and has saint name
1 San Jose 1015785 176.53 5754.177760 True
2 Sacramento 485199 97.92 4955.055147 False
0 San Francisco 852469 46.87 18187.945381 False
参考文献:Google AI Study
觉得写的不错的朋友可以点一个 喜欢♥ ~
谢谢你的支持!
网友评论