1、Pandas简介
pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。
pandas主要使用的是两个数据结构Series和Dataframe,我们先导入它们以及相关模块:
# -*- coding:utf-8 -*-
import numpy as np
from pandas import Series, DataFrame
2、Pandas数据结构:Series
一般来说,Series可以被认为是一维数组,Series与一维数组最主要的区别是Series具有索引(index),可以与另一个程序中常见的数据结构联系起来。
2.1 Series的创建
创建Series的基本格式是s = Series(data, index=index, name=name),下面给出几个创建Series的例子。
a = np.random.randn(5)
print ("a is an array:")
print (a)
s = Series(a)
print ("s is a Series:")
print (s)
a is an array:
[-1.24962807 -0.85316907 0.13032511 -0.19088881 0.40475505]
s is a Series:
0 -1.249628
1 -0.853169
2 0.130325
3 -0.190889
4 0.404755
dtype: float64
在创建Series时可以添加index,而且可以使用Series.index查看具体的index,但是需要注意的一点是,当从数组创建Series时,若指定index,那么index长度要和data的长度一致:
s = Series(np.random.randn(5), index = ['a' , 'b' , 'c' , 'd' , 'e'])
print(s)
print(s.index)
a -0.566972
b -0.426072
c 0.787193
d 0.526550
e -1.271557
dtype: float64
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
Series还可以从字典(dict)创建:
d = {'a' : 0. , 'b' : 1. , 'c' : 2}
print("d is a dict:")
print(d)
s = Series(d)
print( "s is a Series:")
print(s)
d is a dict:
{'a': 0.0, 'b': 1.0, 'c': 2}
s is a Series:
a 0.0
b 1.0
c 2.0
dtype: float64
当使用字典创建Series指定index时(index长度不必和字典相同):
s=Series(d, index=['b', 'c', 'd', 'a'])
print(s)
b 1
c 2
d NaN
a 0
dtype: float64
我们可以观察到两点:一是字典创建的Series,数据将按index的顺序重新排列;二是index长度可以和字典长度不一致,如果多了的话,pandas将自动为多余的index分配NaN(not a number,pandas中数据缺失的标准记号),当然index少的话就截取部分的字典内容。
如果数据就是一个单一的变量,如数字4,那么Series将重复这个变量:
s=Series(4., index=['a', 'b', 'c', 'd', 'e'])
print(s)
a 4.0
b 4.0
c 4.0
d 4.0
e 4.0
dtype: float64
2.2 Series数据的访问
访问Series数据可以和数组一样使用下标,也可以像字典一样使用索引,还可以使用一些条件过滤:
s = Series(np.random.randn(10),index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
print(s[0])
0.369119712193
print(s[:2])
a 1.850786
b -2.170505
dtype: float64
print(s[s > 0.5])
a 0.865307
b 1.545784
g 2.530915
dtype: float64
3、Pandas数据结构:DataFrame
在使用DataFrame之前,我们说明一下DataFrame的特性。DataFrame是将数个Series按列合并而成的二维数据结构,每一列单独取出来是一个Series,这和SQL数据库中取出的数据是很类似的。所以,按列对一个DataFrame进行处理更为方便,用户在编程时注意培养按列构建数据的思维。DataFrame的优势在于可以方便地处理不同类型的列,因此,就不要考虑如何对一个全是浮点数的DataFrame求逆之类的问题了,处理这种问题还是把数据存成NumPy的matrix类型比较便利一些。
3.1 DataFrame的创建
首先来看如何从字典创建DataFrame。DataFrame是一个二维的数据结构,是多个Series的集合体。我们先创建一个值是Series的字典,并转换为DataFrame:
d = {'one' : Series([1.,2.,3.] , index=['a' , 'b' , 'c']),
'two' : Series([1.,2.,3.,4.] , index=['a' , 'b' , 'c' , 'd'])}
df = DataFrame(d)
print(df)
one two
a 1.0 1.0
b 2.0 2.0
c 3.0 3.0
d NaN 4.0
可以指定所需的行和列,若字典中不含有对应的元素,则置为NaN:
df = DataFrame(d , index=['r' , 'd' , 'a'] , columns=['two' , 'three'])
print(df)
two three
r NaN NaN
d 4.0 NaN
a 1.0 NaN
可以使用dataframe.index和dataframe.columns来查看DataFrame的行和列,dataframe.values则以数组的形式返回DataFrame的元素:
print ("DataFrame index:")
print (df.index)
print ("DataFrame columns:")
print (df.columns)
print ("DataFrame values:")
print (df.values)
DataFrame index:
Index(['r', 'd', 'a'], dtype='object')
DataFrame columns:
Index(['two', 'three'], dtype='object')
DataFrame values:
[[nan nan]
[4.0 nan]
[1.0 nan]]
DataFrame也可以从值是数组的字典创建,但是各个数组的长度需要相同:
d = {'one' : [1. ,2. , 3. , 4.],
'two' : [4. ,3. , 2. , 1.]}
df = DataFrame(d , index= ['a' , 'b' , 'c' , 'd'])
print(df)
one two
a 1.0 4.0
b 2.0 3.0
c 3.0 2.0
d 4.0 1.0
值非数组时,没有这一限制,并且缺失值补成NaN:
d = [{'a' : 1.6 , 'b' : 2},
{'a': 3., 'b':6 , 'c' : 9}]
df = DataFrame(d )
print(df)
a b c
0 1.6 2 NaN
1 3.0 6 9.0
在实际处理数据时,有时需要创建一个空的DataFrame,可以这么做:
df = DataFrame()
print(df)
Empty DataFrame
Columns: []
Index: []
另一种创建DataFrame的方法十分有用,那就是使用concat函数基于Serie或者DataFrame创建一个DataFrame
a = Series(range(5))
b = Series(np.linspace(4 , 20 , 5))
df = pd.concat([a , b] , axis= 1)
print(df)
0 1
0 0 4.0
1 1 8.0
2 2 12.0
3 3 16.0
4 4 20.0
其中的axis=1表示按列进行合并,axis=0表示按行合并,并且,Series都处理成一列,所以这里如果选axis=0的话,将得到一个10×1的DataFrame。下面这个例子展示了如何按行合并DataFrame成一个大的DataFrame:
df = DataFrame()
index = ['alpha', 'beta', 'gamma', 'delta', 'eta']
for i in range(5):
a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]])
df = pd.concat([df, a], axis=0)
print (df)
0 1 2 3 4
alpha 0.0 0.0 0.0 0.0 0.0
beta 1.0 2.0 3.0 4.0 5.0
gamma 2.0 4.0 6.0 8.0 10.0
delta 3.0 6.0 9.0 12.0 15.0
eta 4.0 8.0 12.0 16.0 20.0
3.2 DataFrame数据的访问
首先,再次强调一下DataFrame是以列作为操作的基础的,全部操作都想象成先从DataFrame里取一列,再从这个Series取元素即可。可以用datafrae.column name选取列,也可以使用dataframe[]操作选取列,我们可以马上发现前一种方法只能选取一列,而后一种方法可以选择多列。若DataFrame没有列名,[]可以使用非负整数,也就是“下标”选取列;若有列名,则必须使用列名选取,另外datafrae.column_name在没有列名的时候是无效的:
print (df[1])
print (type(df[1]))
df.columns = ['a' , 'b' , 'c' , 'd' , 'e']
print(df['b'])
print(type(df['b']))
print(df.b)
print(type(df.b))
print(df[['a' , 'd']])
print(type(df[['a' , 'd']]))
alpha 0.0
beta 2.0
gamma 4.0
delta 6.0
eta 8.0
Name: 1, dtype: float64
<class 'pandas.core.series.Series'>
alpha 0.0
beta 2.0
gamma 4.0
delta 6.0
eta 8.0
Name: b, dtype: float64
<class 'pandas.core.series.Series'>
alpha 0.0
beta 2.0
gamma 4.0
delta 6.0
eta 8.0
Name: b, dtype: float64
<class 'pandas.core.series.Series'>
a d
alpha 0.0 0.0
beta 1.0 4.0
gamma 2.0 8.0
delta 3.0 12.0
eta 4.0 16.0
<class 'pandas.core.frame.DataFrame'>
以上代码使用了dataframe.columns为DataFrame赋列名,并且我们看到单独取一列出来,其数据结构显示的是Series,取两列及两列以上的结果仍然是DataFrame。访问特定的元素可以如Series一样使用下标或者是索引:
print(df['b'][2])
print(df['b']['gamma'])
4.0
4.0
若需要选取行,可以使用dataframe.iloc按下标选取,或者使用dataframe.loc按索引选取:
print(df.iloc[1])
print(df.loc['gamma'])
a 1.0
b 2.0
c 3.0
d 4.0
e 5.0
Name: beta, dtype: float64
a 2.0
b 4.0
c 6.0
d 8.0
e 10.0
Name: gamma, dtype: float64
选取行还可以使用切片的方式或者是布尔类型的向量:
print("Selecting by slices:")
print(df[1:3])
bool_vec = [True, False, True,True, False]
print("Selecting by boolean vector:")
print(df[bool_vec])
Selecting by slices:
a b c d e
beta 1.0 2.0 3.0 4.0 5.0
gamma 2.0 4.0 6.0 8.0 10.0
Selecting by boolean vector:
a b c d e
alpha 0.0 0.0 0.0 0.0 0.0
gamma 2.0 4.0 6.0 8.0 10.0
delta 3.0 6.0 9.0 12.0 15.0
行列组合起来选取数据:
print(df[['b' , 'd']].iloc[[1,3]])
print(df.iloc[[1,3]][['b','d']])
print(df[['b','d']].loc[['beta' , 'delta']])
print(df.loc[['beta' , 'delta']][['b' , 'd']])
b d
beta 2.0 4.0
delta 6.0 12.0
b d
beta 2.0 4.0
delta 6.0 12.0
b d
beta 2.0 4.0
delta 6.0 12.0
b d
beta 2.0 4.0
delta 6.0 12.0
如果不是需要访问特定行列,而只是某个特殊位置的元素的话,dataframe.at和dataframe.iat是最快的方式,它们分别用于使用索引和下标进行访问:
print(df.iat[2,3])
print(df.at['gamma' , 'd'])
8.0
8.0
dataframe.ix可以混合使用索引和下标进行访问,唯一需要注意的地方是行列内部需要一致,不可以同时使用索引和标签访问行或者列,不然的话,将会得到意外的结果:
print(df.ix['gamma' , 4])
print(df.ix[['delta' , 'gamma'] , [1,4]])
print(df.ix[[1,2],['b','e']])
10.0
b e
delta 6.0 15.0
gamma 4.0 10.0
b e
beta 2.0 5.0
gamma 4.0 10.0
- DataFrame的基本功能:
4.1 排序和排名
根据索引排序,对于DataFrame可以指定轴。
obj = Series(range(4), index = ['d', 'a', 'b', 'c'])
print (obj.sort_index())
frame = DataFrame(np.arange(8).reshape((2, 4)),
index = ['three', 'one'],
columns = list('dabc'))
print (frame.sort_index())
print (frame.sort_index(axis = 1))
print (frame.sort_index(axis = 1, ascending = False))
a 1
b 2
c 3
d 0
dtype: int32
d a b c
one 4 5 6 7
three 0 1 2 3
a b c d
three 1 2 3 0
one 5 6 7 4
d c b a
three 0 3 2 1
one 4 7 6 5
根据值排序
obj = Series([4, 7, -3, 2])
print (obj.sort_values())
2 -3
3 2
0 4
1 7
dtype: int64
对于DataFrame,可以指定按值排序的列
frame = DataFrame({'b':[4, 7, -3, 2], 'a':[0, 1, 0, 1]})
print (frame)
print (frame.sort_values(by = 'b') )
print (frame.sort_values(by = ['a', 'b']))
a b
0 0 4
1 1 7
2 0 -3
3 1 2
a b
2 0 -3
3 1 2
0 0 4
1 1 7
a b
2 0 -3
0 0 4
3 1 2
1 1 7