1. 教程简介
本教程分为上、下两节,主要针对机器学习数据处理做的简单教程。本教程主要不是讲解pandas函数的使用,而是实验性的操作学习方式,对于使用本教程的学者,可以根据课程一步一步去实验,对于不懂的函数以及实现方式可以在官网进行查询。注意,重点还是动手自己操作。
2. Pandas简介
pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。pandas有三种数据结构形式,分别是Series,DataFrame和索引对象。本教程上节也主要是讲解着几种结构形式,下节讲解pandas在特征工程中常用的操作。
3. Series结构
3.1 构造和初始化Series
import pandas as pd
import numpy as np
3.1.1 通过list来构建
# Series是一个一维的数据结构,下面是一些初始化Series的方法
s = pd.Series([5, 9, "shanghai","shenzhen",7,5.2])
s
输出:
# 切片读取
s[1:3]
输出:
# pandas会默认用0到n-1来作为Series的index,但是我们也可以自己指定index。index我们可以把它理解为dict里面的key。
s = pd.Series([5, 9, "shanghai","shenzhen",5.2],
index=["A", "B", "C", "D", "E"])
s
输出:
# 通过制定的key获取元素
s["C"]
输出: 'shanghai'
3.1.2 通过dictionary来构建
cities = {"Shanghai": 90000, "Foshan": 4500, "Dongguan": 5500, "Beijing": 6600, "Nanjing": 8000, "Lanzhou": None}
apts = pd.Series(cities, name="price")
apts
输出:
3.1.2 通过numpy ndarray来构建
s = pd.Series(np.random.randn(6), index=list("abcdef"))
s
输出:
3.2 数据的选择
对于Series我们可以向list一样进行元素的获取。
3.2.1 通过list方式
cities = {"Shanghai": 90000, "Foshan": 4500, "Dongguan": 5500, "Beijing": 6600, "Nanjing": 8000, "Lanzhou": None}
apts = pd.Series(cities, name="price")
# 获取元素 list方式
apts[[4,3,2]]
输出:
3.2.2 通过切片方式
# 切片方式
apts[3:]
输出:
# 切片方式 :-2表示从0到末尾第二个
apts[:-2]
输出:
# 读取到倒数第一个
apts[:-1]
输出:
# 从第一个到最后一个
apts[1:]
输出:
3.2.2 通过key获取
# 通过key获取,前面定义的index就是用来选择数据的
apts["Shanghai"]
输出:90000.0
# 通过key组成的list获取元素,对于Series没有的就返回空
apts[["Shenzhen", "Nanjing", "Dongguan"]]
输出:
3.2.3 判断元素是否存在
"Shanghai" in apts
输出:True
"Chongqing" in apts
输出:False
3.2.4 用get读取元素
# 用读取元素,当Series中没有这个元素时,可以返回我们制定的数,这里定义为0
apts.get("Shanghai", 0)
输出:90000.0
# apts中没有Shenzhen
apts.get("Shenzhen", 0)
输出:0
3.2.5 用过bool类型获取元素
#获取小于7000的元素
apts[apts < 7000]
输出:
# 返回大于平均值的数
apts[apts > apts.median()]
输出:
# 具体的过程
less_than_7000 = apts < 50000
less_than_7000
输出:
apts[less_than_7000]
输出:
3.3 Series元素赋值
对于Series赋值非常简单,对于以上我们已经拿到了Series,那我们可以直接对其赋值就可以。
apts["Shanghai"] = 68000
apts
输出:
# 小于50000的都赋值给60000
apts[apts < 50000] = 60000
apts
输出:
3.4 Series数学运算
# 每个元素都乘上2
apts * 2
输出:
# 每个元素都除于2
apts / 2
输出:
# 每个元素都加上10000,但是对于值为NAN的元素你做运算
apts + 10000
输出:
# 平方运算
apts ** 2
输出:
# 开根号
np.square(apts)
输出:
3.5 缺损值处理
# 判断哪个值不是NaN
apts.notnull()
输出:
# 判断是否有NaN
apts.isnull()
输出:
# 对缺损值进行填充
apts[apts.isnull()] = apts.mean()
apts
输出:
4. Dataframe结构
Dataframe就像是一张表格,而Series表示的是一个以为数组,Dataframe则是一个二维数组,可以类比成一张Excel表格,而是Dataframe的一行或者一列则是一个Series。对于Dataframe的行用index表示,列用columns表示。
4.1 Dataframe的创建
4.1.1 通过dictionary创建
dataframe可以是有一个dictionary构造来创建。
data = {'city': ['Shanghai', 'Nanjing', 'Lanzhou', 'Shangsha', 'Guizhou', 'Xian'],
'year': [2017,2018,2017,2018,2018,2017],
'population': [2100, 600, 800, 700, 560, 900]}
pd.DataFrame(data)
输出:
# 可以指定columns的名字和顺序
pd.DataFrame(data, columns=["year", "city", "population"])
输出:
# 创建时指定index和columns
frame = pd.DataFrame(data, columns=["year", "city", "population", "debt"],
index=["one", "two", "three", "four", "five", "six"])
frame
输出:
4.1.2 通过Series创建
cars = pd.Series({"Beijing": 300000, "Shanghai": 350000, "Shenzhen": 300000,
"Tianjian": 200000, "Guangzhou": 250000, "Chongqing": 150000})
cities = {"Shanghai": 90000, "Foshan": 4500, "Dongguan": 5500, "Beijing": 6600, "Nanjing": 8000, "Lanzhou": None}
apts = pd.Series(cities, name="price")
df = pd.DataFrame({"apts": apts, "cars": cars})
df
输出:
4.1.3 通过dicts的list来构建Dataframe
data = [{"Beijing": 1000, "Shanghai": 2500, "Nanjing": 9850}, {"Beijing": 5000, "Shanghai": 4600, "Nanjing": 7000}]
pd.DataFrame(data)
输出:
# 定义index
data = [{"Beijing": 1000, "Shanghai": 2500, "Nanjing": 9850}, {"Beijing": 5000, "Shanghai": 4600, "Nanjing": 7000}]
pd.DataFrame(data, index=["salary", "other"])
输出:
4.2 获取Dataframe的值
4.2.1 通过列名的方式
# 通过列名
frame["city"]
输出:
# 也可以用这种方式,与上面的效果一样
frame.year
输出:
# 判断类型
type(frame.year)
输出:pandas.core.series.Series
4.2.2 通过loc函数
# 通过自己定义的index获取
frame.loc["three"]
输出:
# 通过行列名字或者
frame.loc["three", "city"]
输出:Lanzhou
4.2.2 通过iloc函数
通过iloc方法可以拿到行和列,直接按照index的顺序来取。可以当做numpy的ndarray的二维数组来操作。
# 获取前三行
frame.iloc[0:3]
输出:
# 切片操作
frame.iloc[0:3, 1:3]
输出:
4.3 Dataframe赋值
对于以上获取到Dataframe以后,要想对其赋值是很简单的。
frame.loc["one", "population"] = 5555
frame
输出:
# 给一整列赋值
frame["debt"] = 1000
frame
输出:
# 对整行赋值
frame.loc["six"] = np.NaN
frame
输出:
4.4 获取columns和index
# 获取columns名
frame.columns
输出:Index(['year', 'city', 'population', 'debt'], dtype='object')
# 获取index名
frame.index
输出:Index(['one', 'two', 'three', 'four', 'five', 'six'], dtype='object')
# 输出columns名
for name in frame.columns:
print(name)
输出:
4.5 用Series指定Dataframe要修改的值
用Series来指定需要修改的index以及相应的value,没有指定的默认用NaN。
val = pd.Series([100, 200, 300], index=['two', 'three', 'four'])
frame["debt"] = val * 1000
frame
输出:
4.6 给index与columns指定名字
frame.index.name = "row"
frame.columns.name = "columns"
frame
输出:
4.6 把Dataframe转换成ndarray
有时候某些操作需要对数据进行装换numpy.ndarray类型才能进行处理,所以要用values对Dataframe进行转换或者as_matrix函数。
df.values
输出:
# 判定类型
type(df.values)
输出:numpy.ndarray
# 另一个方法
df.as_matrix()
输出:
4.7 Dataframe删除操作
data = DataFrame(np.arange(16).reshape((4,4)),
index = ['Ohio','Colorado','Utah','New York'],
columns = ['one','two','three','four'])
print(data)
#放一个标量就删除一行或一列,放一个数组就删除一组行或者一组列
print(data.drop(['Colorado','Ohio']))
#axis=0:从上到下,沿着行的方向操作,axis=1:从左到右,沿着列的方向操作
print(data.drop('two',axis=1))
print(data.drop(['two','four'],axis=1))
输出:
4.8 统计描述
df = DataFrame([[1.4, np.nan], [7.1, -4.5], [np.nan, np.nan], [0.75, -1.3]],
index=['a', 'b', 'c', 'd'],
columns=['one', 'two'])
print(df)
# 每一列的统计信息(自己尝试一下非数值型变量统计结果是什么?)
df.describe()
输出:
# get index object
obj = pd.Series(range(3), index=["a", "b", "c"])
index = obj.index
index
5. index
5.1 index object
obj = pd.Series([4.5, 2.6, -1.8, 9.4], index=["d", "b", "a", "c"])
obj
输出:Index(['a', 'b', 'c'], dtype='object')
5.2 index 一些操作
# 获取index元素
index[1:]
输出:Index(['b', 'c'], dtype='object')
# index的值是不能被更改的
# index[0] = 6
# 构造index
index = pd.Index(np.arange(3))
index
输出:Int64Index([0, 1, 2], dtype='int64')
# index的使用
obj2 = pd.Series([2,5,7], index=index)
obj2
输出:
# 判断index元素
obj2.index is index
输出:True
# 注意与上面的区别
obj2.index is np.arange(3)
输出:False
obj2.index == np.arange(3)
输出:array([ True, True, True], dtype=bool)
# 判断index是否存在
pop = {'Nanjing': {2017: 1000, 2018:1100},
'Guangzhou': {2016:800, 2017:850, 2018:880}}
frame3 = pd.DataFrame(pop)
print(frame3)
print("Shanghai" in frame3.columns)
输出:
2017 in frame3.index
输出:True
5.3 index 索引与切片
# 索引,按照index的元素进行索引
obj = pd.Series(range(3), index=["a", "b", "c"])
obj["a"]
输出:0
# 使用index默认的数字进行索引
obj[[1,2]]
输出:
# 按照bool值进行索引
obj[obj<2]
输出:
# 切片方式
obj["b":"c"]
输出:
obj["b":]
输出:
5.4 DataFrame 的index
cars = pd.Series({"Beijing": 300000, "Shanghai": 350000, "Shenzhen": 300000,
"Tianjian": 200000, "Guangzhou": 250000, "Chongqing": 150000})
cities = {"Shanghai": 90000, "Foshan": 4500, "Dongguan": 5500, "Beijing": 6600, "Nanjing": 8000, "Lanzhou": None}
apts = pd.Series(cities, name="price")
df = pd.DataFrame({"price": apts, "cars": cars})
df
输出:
# 通过index获取元素,没有的列输出NaN
df.loc["Beijing":"Guangzhou", ["price", "other"]]
输出:
# 切片获取
df.iloc[2:4, 1:3]
输出:
注:loc与iloc的区别,loc可以用名字进行选择,iloc用index数字进行选择
5.4 DataFrame 条件选择
5.4 DataFrame 的index
输出:
# 条件选择
df[df.price > 5000]
输出:
5.5 Series index重排
把一个Series或者DataFrame按照新的index顺序进行重排
obj = pd.Series([4.5, 2.6, -1.8, 9.4], index=["d", "b", "a", "c"])
obj
输出:
# 对index进行重排
obj.reindex(["a", "b", "c", "d", "e"])
输出:
5.6 Series reindex对NaN进行填充
把一个Series或者DataFrame按照新的index顺序进行重排
obj.reindex(["a", "b", "c", "d", "e"], fill_value=obj.mean())
输出:
# 如果为空,填充前面index的值
obj3.reindex(range(6), method="ffill")
输出:
# 获取后面的值,进行填充
obj3.reindex(range(6), method="bfill") # backward fill
输出:
5.7 DataFrame index重排
data = {'city': ['Shanghai', 'Nanjing', 'Lanzhou', 'Shangsha', 'Guizhou', 'Xian'],
'year': [2017,2018,2017,2018,2018,2017],
'population': [2100, 600, 800, 700, 560, 900]}
frame = pd.DataFrame(data, columns=["year", "city", "population", "debt"],
index=["one", "two", "three", "four", "five", "six"])
frame2 = frame.reindex(["one", "three", "four", "eight"])
frame2
输出:
# 对列进行重排
frame.reindex(columns=["city", "year", "population"])
输出:
5.8 对index进行删除
对于使用drop删除index并不能真正,只是删除之后,返回剩余的部分。
obj3 = pd.Series(["blue", "red", "yello"], index=[1,3,5])
obj4 = obj3.drop(5)
print(obj4)
obj3
输出:
obj3.drop([3,5])
输出:
# 对dataframe进行drop
data = {'city': ['Shanghai', 'Nanjing', 'Lanzhou', 'Shangsha', 'Guizhou', 'Xian'],
'year': [2017,2018,2017,2018,2018,2017],
'population': [2100, 600, 800, 700, 560, 900]}
frame = pd.DataFrame(data, columns=["year", "city", "population", "debt"],
index=["one", "two", "three", "four", "five", "six"])
frame.drop(["debt", "year"], axis=1)
输出:
5.8 Series多层index
# Series的多层index
# 构造多层index
data = pd.Series(np.random.randn(10), index=
[['a','a','a','b','b','c','c','c','d','d'],
[1,2,3,1,2,1,2,3,1,2]])
print(data)
输出:
# 获取index object
data.index
输出:
# 通过index获取元素
data.b
输出:
# 切片方式
data["b":"c"]
输出:
# 通过默认的index
data[2:5]
输出:
5.9 hierarchical indexing和DataFrame转换
可以通过unstack和stack进行转换。
type(data.unstack())
输出:data.unstack().stack()
data.unstack().stack()
输出:
5.10 hierarchical indexing & DataFrame
frame = pd.DataFrame(np.arange(12).reshape((4,3)),
index = [['a','a','b','b'], [1,2,1,2]],
columns = [['xiaoming', 'lisi', 'lisi'], ['one', 'tow', 'three']])
frame
输出:
# 取值
frame.loc["a", 1]["lisi"]["tow"]
输出:1
6. CSV文件读取
6.1 默认读取方式
goog = pd.read_csv("data/GOOG.csv")
goog.head() #输出前几个
输出:
6.2 指定index读取
# 读进来的时候设置index,声明哪里列是日期
goog = pd.read_csv("data/GOOG.csv", index_col=0, parse_dates=[0])
goog.head()
输出:
# 获取index
goog.index
输出:'2004-08-19', '2004-08-20', '2004-08-23', '2004-08-24'..........
6.3 CSV文件存储
使用to_csv函数。
# 以\t的方式进行分隔
df.to_csv("data/test.tsv", sep="\t")
6. 作图
# 根据上面的数据作图
# 把图片输出到当前界面
%matplotlib inline
goog["Adj Close"].plot()
输出:
# 1/1/2010", periods=1000):从这个日期开始,往后推一千天
ts = pd.Series(np.random.randn(1000)*100, index=pd.date_range("1/1/2010", periods=1000))
ts = ts.cumsum()
ts.plot()
输出:
# dataframe直接绘制图像
df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list("ABCD"))
df = df.cumsum()
df.plot()
输出:
# 绘制柱状图
df.iloc[5].plot(kind="bar")
输出:
# 状图图
# 横着画
df.head().plot.barh(stacked=True)
# 竖着 画
# df.head().plot.bar(stacked=True)
输出:
对于机器学习之pandas的应用上节到这里结束了,对于跟着这个教程学习的同学,一定要多操作,多动手。