pandas入门(上)
来源:互联网 发布:asp.net程序员 编辑:程序博客网 时间:2024/06/17 02:36
pandas含有使数据分析工作变得更快更简单的高级数据结构和操作工具。pandas是基于NumPy构建的,它使得以NumPy为中心的应用变得更加简单。pandas具有以下功能:
- 具备按轴自动或显示数据对齐功能的数据结构。这可以防止许多由于数据未对齐以及来自不同数据源(索引方式不同)的数据而导致的常见错误
- 集成时间序列功能
- 既能处理时间序列数据也能处理非时间序列数据的数据结构
- 数学运算和约减(比如对某个轴求和)可以分局不同的元数据(轴编号)进行
- 灵活处理缺失数据
- 合并及其他出现在常见数据库(例如基于SQL的)中的关系型运算
在后续部分中,我们使用下面这样的pandas引入约定,由于Series和DataFrame用的次数非常多,所以将其引入本地命名空间中会更方便:
from pandas import Series, DataFrameimport pandas as pdimport numpy as np
pandas的数据结构介绍
要使用pandas,我们首先要熟悉它的两个主要数据结构:Series和DataFrame。
Series
Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及与之相关的数据标签(即索引)组成。仅由一组数组即可产生最简单的Series:
obj1 = Series([4,5,7,-1])obj1
0 41 52 73 -1dtype: int64
Series的字符串表现形式为:索引在左边,值在右边。因为我们没有为数据指定索引,所以Series会自动创建一个从0到N-1(N为数组长度)的整数型索引。可以通过Series的values和index属性获取其数组表示形式和索引对象:
obj1.values
array([ 4, 5, 7, -1], dtype=int64)
obj1.index
RangeIndex(start=0, stop=4, step=1)
通常,我们希望所创建的Series带有一个可以对各个数据点进行标记的索引:
obj2 = Series([4,7,-5,3],index=['d','a','c','b'])obj2
d 4a 7c -5b 3dtype: int64
obj2.index
Index(['d', 'a', 'c', 'b'], dtype='object')
可以通过索引的方式选取Series中的单个或一组值:
obj2['a']
7
obj2[['a','b']]
a 7b 3dtype: int64
NumPy中的数组运算(如根据布尔型数组进行过滤、标量乘法、应用数学函数等)都会保留索引和值之间的连接:
obj2
d 4a 7c -5b 3dtype: int64
obj2[obj2 > 2]
d 4a 7b 3dtype: int64
obj2 * 2
d 8a 14c -10b 6dtype: int64
还可以将Series看成一个定长的有序字典,因为它是索引值到数据值的映射。它可以用在许多原本需要字典参数的函数中:
'b' in obj2
True
for k in obj2.keys(): print(k)
dacb
如果数据被存放在一个Python字典中,也可以直接通过这个字典来创建Series:
sdata = {'Ohio':35000,'Texas':71000,'Oregon':16000,'Utah':5000}obj3 = Series(sdata)obj3
Ohio 35000Oregon 16000Texas 71000Utah 5000dtype: int64
如果只传入一个字典,则结果Series中的索引就是原字典的键(有序排列):
states = ['California','Ohio','Oregon','Texas']obj4 = Series(sdata,index=states)obj4
California NaNOhio 35000.0Oregon 16000.0Texas 71000.0dtype: float64
在上面的例子中,sdata中和states索引相匹配的那3个值会被找出来并放到相应的位置上,但是由于“California”所对应的sdata值找不到,所以其结果就是NaN(Not a Number)。pandas中的isnull和notnull函数可用于检测缺失数据:
pd.isnull(obj4)
California TrueOhio FalseOregon FalseTexas Falsedtype: bool
pd.notnull(obj4)
California FalseOhio TrueOregon TrueTexas Truedtype: bool
Series也有类似的实例方法:
obj4.isnull()
California TrueOhio FalseOregon FalseTexas Falsedtype: bool
对于许多应用,Series最重要的一个功能就是:他在算术运算中会自动对齐不同索引的数据:
obj3
Ohio 35000Oregon 16000Texas 71000Utah 5000dtype: int64
obj4
California NaNOhio 35000.0Oregon 16000.0Texas 71000.0dtype: float64
obj3 + obj4
California NaNOhio 70000.0Oregon 32000.0Texas 142000.0Utah NaNdtype: float64
Series对象本身及其索引都有一个name属性,该属性跟pandas其他的关键功能非常密切:
obj4.name = 'population'obj4.index.name = 'state'obj4
stateCalifornia NaNOhio 35000.0Oregon 16000.0Texas 71000.0Name: population, dtype: float64
Series的索引可以通过复制的方式就地修改:
obj1.index
RangeIndex(start=0, stop=4, step=1)
obj1.index = ['Bob','Steve','Jeff','Ryan']obj1
Bob 4Steve 5Jeff 7Ryan -1dtype: int64
DataFrame
DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引,又有列索引,它可以被看成是一个由Series组成的字典(共用一个索引)。构建DataFrame的方法有很多,最常用的一种是直接传入一个由等长列表或ndarray组成的字典,DataFrame会自动加上索引,且全部列会被有序排列:
data = {'state':['Ohio','Ohio','Ohio','Nevada','Nevada'], 'year':[2000,2001,2002,2001,2002], 'pop':[1.5,1.7,3.6,2.4,2.9]}frame1 = DataFrame(data)frame1
如果指定了列序列,那么DataFrame的列就会按照指定顺序进行排列:
DataFrame(data,columns=['year','state','pop'])
和Series一样,如果传入的列在数据中找不到,就会产生NaN:
frame2 = DataFrame(data,columns=['year','state','pop','debt'],index=['one','two','three','four','five'])frame2
frame2.columns
Index(['year', 'state', 'pop', 'debt'], dtype='object')
通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series:
frame2['state']
one Ohiotwo Ohiothree Ohiofour Nevadafive NevadaName: state, dtype: object
frame2.year
one 2000two 2001three 2002four 2001five 2002Name: year, dtype: int64
注意,返回的Series拥有与原DataFrame相同的索引,且其name属性也已经被相应地设置好了。行也可以通过位置或名称的方式进行获取,比如用索引字段loc:
frame2.loc['three']
year 2002state Ohiopop 3.6debt NaNName: three, dtype: object
列可以通过赋值的方式进行修改。例如,我们可以给那个空的“debt”列赋上一个标量值或一组值:
frame2['debt'] = 16.5frame2
frame2['debt'] = np.arange(5)frame2
将列表或数组赋值给某个列时,其长度必须与DataFrame的长度相匹配。如果赋值的是一个Series,则会精确匹配DataFrame的索引,所有的空位都会被填上缺失值:
val = Series([-1.2,-1.5,-1.7],index=['two','four','three'])frame2['debt'] = valframe2
为不存在的列赋值为创建一个新的列。关键字del用于删除列:
frame2['eastern'] = frame2.state == 'Ohio'frame2
del frame2['eastern']frame2.columns
Index(['year', 'state', 'pop', 'debt'], dtype='object')
注意:通过索引方式返回的列只是相应数据的视图而已,并不是副本。因此,对返回的Series所做的任何就地修改全都会反应到原DataFrame上。通过copy方法即可显式地复制列。
另一种常见的数据形式是嵌套字典,如果将它传递给DataFrame,那么外层字典的键将被作为列,而内层字典的键将被作为行索引:
pop = {'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,2002:3.6}}frame3 = DataFrame(pop)frame3
当然,我们也可以对结果进行转置:
frame3.T
内层字典的键会被合并、排序以形成最终的1索引。如果显式地指定了索引,则不会这样:
DataFrame(pop,index=[2001,2002,2003])
由Series组成的字典也是差不多的用法:
pdata = {'Ohio':frame3['Ohio'][:-1], 'Nevada':frame3['Nevada'][:2]}DataFrame(pdata)
下面列出了DataFrame构造函数所能接受的各种数据。
如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来:
frame3.index.name = 'year'frame3.columns.name = 'state'frame3
跟Series一样,values属性也会以二维ndarry的形式返回DataFrame中的数据:
frame3.values
array([[ nan, 1.5], [ 2.4, 1.7], [ 2.9, 3.6]])
如果DataFrame各列的数据类型不同,则值数组的数据类型就会选用能兼容素有列的数据类型:
frame2.values
array([[2000, 'Ohio', 1.5, nan], [2001, 'Ohio', 1.7, -1.2], [2002, 'Ohio', 3.6, -1.7], [2001, 'Nevada', 2.4, -1.5], [2002, 'Nevada', 2.9, nan]], dtype=object)
索引对象
pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等)。构建Series或DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index:
obj = Series(range(3),index=['a','b','c'])index = obj.indexindex
Index(['a', 'b', 'c'], dtype='object')
index[1:]
Index(['b', 'c'], dtype='object')
Index对象是不可修改的(Immutable),因此用户不能对其进行修改:
index[1] = 'd'
---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-46-676fdeb26a68> in <module>()----> 1 index[1] = 'd'E:\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value) 1618 1619 def __setitem__(self, key, value):-> 1620 raise TypeError("Index does not support mutable operations") 1621 1622 def __getitem__(self, key):TypeError: Index does not support mutable operations
不可修改性非常重要,因为这样才能使Index对象在多个数据结构之间安全共享:
index = pd.Index(np.arange(3))obj3 = Series([1.5,-2.5,0],index=index)obj3.index is index
True
下表给出了pandas库中内置的Index类。现在Index还可以被继承重而实现特别的轴索引功能。
除了长的像数组,Index的功能也类似一个固定大小的集合:
frame3
'Ohio' in frame3.columns
True
2003 in frame3.index
False
每个索引都有一些方法和属性,他们可用于设置逻辑并回答有关该索引所包含的数据的常见问题。下面给出这些函数。
基本功能
重新索引
pandas对象有一个reindex方法,它可以创建一个适应新索引的对象:
obj1 = Series([4.5,7.2,-5.3,3.6],index=['d','a','b','c'])obj1
d 4.5a 7.2b -5.3c 3.6dtype: float64
obj2 = obj.reindex(['a','b','c','d','e'])obj2
a 7.2b -5.3c 3.6d 4.5e NaNdtype: float64
obj1.reindex(['a','b','c','d','e'],fill_value=0)
a 7.2b -5.3c 3.6d 4.5e 0.0dtype: float64
对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。method选项可以实现这种功能。例如,使用ffill可以实现前向填充:
obj3 = Series(['blue','purple','yellow'],index=[0,2,4])obj3
0 blue2 purple4 yellowdtype: object
obj3.reindex(range(6),method='ffill')
0 blue1 blue2 purple3 purple4 yellow5 yellowdtype: object
下面给出了可用的method选项。
对于DataFrame,reindex可以修改行索引或列索引,也可以两个都修改。如果只传入一个序列,则会重新索引行:
frame1 = DataFrame(np.arange(9).reshape((3,3)),index=['a','c','d'],columns=['Ohio','Texas','California'])frame1
frame2 = frame1.reindex(['a','b','c','e'])frame2
使用关键字columns可以重置列索引:
frame1.reindex(columns=['Texas','Uath','Ohio'])
可以同时对行和列使用reindex,但是插值只能按行(轴0)使用:
frame1.reindex(index=['a','b','c','d'],columns=['Ohio','Texas','California'],method='pad')
利用loc的标签索引功能,重新索引任务会更简洁:
frame1.loc[['a','b','c','d'],['Ohio','Texas','California']]
丢弃指定轴上的项
使用drop方法可以丢弃某条轴上的一个或多个项,该方法返回一个在指定轴上删除了指定值的新对象:
obj = Series(np.arange(5),index=['a','b','c','d','e'])obj
a 0b 1c 2d 3e 4dtype: int32
new_obj = obj.drop('c')new_obj
a 0b 1d 3e 4dtype: int32
obj.drop(['d','c'])
a 0b 1e 4dtype: int32
对于DataFrame,可以删除任意轴上的索引值:
df = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio','Colorado','Utah','New York'], columns=['one','two','three','four'])df
df.drop(['Colorado','Ohio'])
df.drop('two',axis=1)
索引、选取和过滤
Series索引类似于NumPy数组的索引,不过Series索引的值不只可以是整数。对于Series来说,利用标签的切片运算与普通的Python切片运算不同,它的末端是包含的(即闭区间):
obj = Series(np.arange(4),index=['a','b','c','d'])obj
a 0b 1c 2d 3dtype: int32
obj['a':'c']
a 0b 1c 2dtype: int32
对DataFrame进行索引就是获取一个或多个列:
data = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio','Colorado','Utah','New York'], columns=['one','two','three','four'])data
data['two']
Ohio 1Colorado 5Utah 9New York 13Name: two, dtype: int32
data['Ohio':'Utah']
另外,还可以通过布尔型DataFrame进行索引:
data < 5
data[data < 5] = 0data
我们还可以使用索引字段loc进行行索引:
data.loc['Colorado',['two','three']]
two 5three 6Name: Colorado, dtype: int32
data.loc[['Colorado','Utah'],['four','two']]
data.iloc[2]
one 8two 9three 10four 11Name: Utah, dtype: int32
data.loc[:'Utah','two']
Ohio 0Colorado 5Utah 9Name: two, dtype: int32
data.loc[data.three > 5, :]
对pandas对象中的数据的选取和重排方式有很多。下面简单总结一下:
算术运算和数据对齐
pandas可以对具有不同索引的对象进行算数运算。在将对象相加时,如果存在不同的索引对,那么结果就是该索引对的并集:
s1 = Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])s2 = Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])s1 + s2
a 5.2c 1.1d NaNe 0.0f NaNg NaNdtype: float64
对于DataFrame,对齐操作会同时发生在行和列上:
df1 = DataFrame(np.arange(9).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])df1
df2 = DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])df2
df1 + df2
在对不同索引的对象进行算数运算时,有时我们希望当一个对象中某个轴标签在另一个对象中找不到时填充一个特殊值,使用算数方法可以解决我们的需求:
df1.add(df2,fill_value=0)
如果某个轴标签在在两个对象中都没有出现,那么结果中该轴标签对应位置的值仍然是NaN,就像上面的运行结果所表示的那样。
DataFrame和Series之间的运算类似于NumPy数组,默认情况下,DataFrame和Series之间的算数运算会将Series的索引匹配到DataFrame的列,然后沿着行向下进行广播:
frame = DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])frame
series = frame.iloc[0]series
b 0d 1e 2Name: Utah, dtype: int32
frame - series
如果某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集:
series2 = Series(range(3),index=['b','e','f'])series2 + frame
如果想要Series匹配其他轴(如匹配行),则必须使用算数方法,并将轴号作为参数传递:
series3 = frame['d']series3
Utah 1Ohio 4Texas 7Oregon 10Name: d, dtype: int32
frame
frame.sub(series3,axis=0)
函数应用和映射
NumPy的ufunc也可用于操作pandas对象:
frame = DataFrame(np.random.randn(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])frame
np.abs(frame)
DataFrame的apply方法可以将函数应用到各行或者各列形成的一维数组上:
f = lambda x: x.max() - x.min()frame.apply(f)
b 2.460983d 1.925833e 2.681498dtype: float64
frame.apply(f,axis=1)
Utah 0.097538Ohio 1.581537Texas 1.474374Oregon 2.463738dtype: float64
另外,元素级的Python函数也是可以使用的,使用applymap方法即可:
frame.applymap(lambda x: '%.2f' % x)
之所以叫applymap,是因为Series有一个用于应用元素级函数的map方法:
frame['e'].map(lambda x:'%.2f'%x)
Utah 0.45Ohio -0.80Texas -0.50Oregon -2.23Name: e, dtype: object
排序
可以使用sort_index对Series和DataFrame的索引进行排序,它返回一个已排序的新对象:
obj = Series(range(4),index=list('dabc'))obj.sort_index()
a 1b 2c 3d 0dtype: int32
对于DataFrame,可以根据任意一轴上的索引进行排序:
frame = DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=list('dabc'))frame.sort_index()
frame.sort_index(axis=1)
默认按照升序排列,但是也可以降序排列:
frame.sort_index(axis=1,ascending=False)
可以使用sort_values方法按值对Series进行排序:
obj = Series([4,7,-3,2])obj.sort_values()
2 -33 20 41 7dtype: int64
对于DataFrame,我们可以在sort_values方法中设置by选项来实现按一个或多个列值的排序:
frame = DataFrame(np.random.randn(4,2),columns=[1,2],index=list('bdac'))frame
frame.sort_values(by=1)
frame.sort_values(by=[2,1])
带有重复值的轴索引
索引的is_unique属性可以告诉你它的值是否唯一:
obj = Series(range(5),index=list('aabbc'))obj
a 0a 1b 2b 3c 4dtype: int32
obj.index.is_unique
False
如果某个索引对应多个值,则返回一个Series;对应单个值的,返回一个标量值:
obj['a']
a 0a 1dtype: int32
obj['c']
4
对DataFrame进行索引时也是如此:
df = DataFrame(np.random.randn(4,3),index=list('aabc'),columns=[1,1,2])df
df[1]
df.loc['a']
- pandas入门(上)
- Pandas入门(上)
- pandas入门
- pandas入门
- Pandas入门
- Pandas入门
- pandas入门
- pandas入门
- Pandas 入门
- pandas入门
- Pandas入门
- python学习笔记一(pandas入门)
- 数据提取(2):pandas库入门
- 十分钟学会pandas(入门级)
- python数据分析(pandas入门)
- pandas教程-----DataFrame入门(12/4)
- Pandas 结构化数据(上)
- Pandas 结构化数据(上)
- linux学习笔记3
- 前端窗口聊天效果
- 新玩法异常火爆,惠民还是另藏骗局
- 5.4.2 RegExp实例方法
- jq动态生成的元素(标签)添加点击事件
- pandas入门(上)
- Tensorlayer学习笔记——LSTM
- python学习—Day43—多线程
- android 跑马灯
- 我对小班研讨课的感受
- md test
- android 串口编程
- 5.1.Spring之自动装配
- 如何搭建Redis集群与Jedis连接集群