Pandas入门学习

作者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai


Pandas是一个数据处理的神器,它有两个最基础的数据结构 SeriesDataFrame ,使得处理数据变得非常方便、快速和简单。

pandas不同的版本之间存在一些不兼容性,为此,我们需要清楚使用的是哪一个版本的pandas,本人使用的版本是 0.18.1

首先,我们先导入需要的模块:

import numpy as np
from pandas import Series, DataFrame

Pandas 数据结构:Series

创建 Series

Series 可以简单地被认为是一维的数组。Series 和一维数组最主要的区别在于 Series 类型具有索引(index)。创建 Series 的基本格式是 s = Series(data, index = index, name = name) ,以下给出几个创建 Series 的例子,比如:

a = np.random.randn(5)
s = Series(a)

# output
0   -0.020420
1    0.596339
2   -0.858304
3   -0.005262
4    1.192183
dtype: float64

# 注意data的数据长度和 index 的长度必须相等
s = Series(np.random.randn(5), index = ['a', 'b', 'c', 'd', 'e'])

# output
a    1.235154
b    0.174400
c   -0.633450
d   -0.155907
e    0.489296
dtype: float64

s.index

# output
Index([u'a', u'b', u'c', u'd', u'e'], dtype='object')

s = Series(np.random.randn(5), index = ['a', 'b', 'c', 'd', 'e'], name = 'my_series')
print s
print 'My Name is:', s.name

# output
a   -1.105137
b   -0.373074
c    1.575859
d   -0.044923
e    1.699821
Name: my_series, dtype: float64
My Name is: my_series

# 利用字典创建
d = {'a': 0, 'b': 1, 'c': 2}
s = Series(d)
print s

# output
a    0
b    1
c    2
dtype: int64

# 使用字典创建Series时,index的长度不必和字典相同
s = Series(d, index = ['b', 'c', 'd', 'a'])
print s

#output
b    1.0
c    2.0
d    NaN
a    0.0
dtype: float64

'''
我们可以观察到两点:
一是字典创建的 Series ,数据将按 index 的顺序重新排列;
二是 index 长度可以和字典长度不一致,如果多了的话,pandas将自动为多余的index分配 NaN(not a number,pandas中数据缺失的标准记号),当然 index 少的话就截取部分的字典内容。
'''

# 如果数据是单一的变量
s = Series(4, index = ['a', 'b', 'c', 'd'])
print s

#output
a    4
b    4
c    4
d    4
dtype: int64
Series 数据的访问

访问 Series 数据可以和数组一样使用下表,也可以像字典一样使用索引,还可以使用一些条件过滤:

s = Series(np.random.randn(10), index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
print s

# output
a   -0.530030
b   -0.453463
c    0.324548
d   -0.773381
e   -1.188608
f    0.483908
g   -0.301127
h    0.870209
i   -1.193555
j   -1.717048
dtype: float64

print s[0]
# output
-0.530030

print s[:2]
# output
a   -0.530030
b   -0.453463
dtype: float64

print s[[2, 0, 4]]
# output
c    0.324548
a   -0.530030
e   -1.188608
dtype: float64

print s[['e', 'i']]
# output
e   -1.188608
i   -1.193555
dtype: float64

print s[s > 0.5]
# output
h    0.870209
dtype: float64

print 'e' in s
# output
True

Pandas 数据结构:DataFrame

在使用DataFrame之前,我们说明一下DataFrame的特性。DataFrame是将数个Series按列合并而成的二维数据结构,每一列单独取出来是一个Series,这和SQL数据库中取出的数据是很类似的。所以,按列对一个DataFrame进行处理更为方便,用户在编程时注意培养按列构建数据的思维。DataFrame的优势在于可以方便地处理不同类型的列,因此,就不要考虑如何对一个全是浮点数的DataFrame求逆之类的问题了,处理这种问题还是把数据存成NumPy的matrix类型比较便利一些。

创建 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
#output
   one  two
a  1.0  1.0
b  2.0  2.0
c  3.0  3.0
d  NaN  4.0

df = DataFrame(d, index=['r', 'd', 'a'], columns=['two', 'three'])
print df
# output
   two three
r  NaN   NaN
d  4.0   NaN
a  1.0   NaN

# 可以使用dataframe.index和dataframe.columns来查看DataFrame的行和列,dataframe.values则以数组的形式返回DataFrame的元素
print df.index
print df.columns
print df.values
# output
Index([u'r', u'd', u'a'], dtype='object')
Index([u'two', u'three'], dtype='object')
array([[nan, nan],
       [4.0, nan],
       [1.0, nan]], dtype=object)

# DataFrame也可以从值是数组的字典创建,但是各个数组的长度需要相同
d = {'one': [1., 2., 3., 4.], 'two': [4., 3., 2., 1.]}
df = DataFrame(d, index=['a', 'b', 'c', 'd'])
print df
# output
   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
# output
     a  b    c
0  1.6  2  NaN
1  3.0  6  9.0

在实际处理数据时,有时候需要创建一个空的DataFrame,可以这样做:

df = DataFrame()
print df
# output
Empty DataFrame
Columns: []
Index: []

另一种创建 DataFrame 的方法十分有用,那就是使用 concat 函数基于 Series 或者 DataFrame 创建一个DataFrame

a = Series(range(5))
b = Series(np.linspace(4, 20, 5))
df = pd.concat([a, b], axis=1)
print df
# output
   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
# output
         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
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']])
# output
alpha    0
beta     2
gamma    4
delta    6
eta      8
Name: 1, dtype: float64
<class 'pandas.core.series.Series'>
alpha    0
beta     2
gamma    4
delta    6
eta      8
Name: b, dtype: float64
<class 'pandas.core.series.Series'>
alpha    0
beta     2
gamma    4
delta    6
eta      8
Name: b, dtype: float64
<class 'pandas.core.series.Series'>
       a   d
alpha  0   0
beta   1   4
gamma  2   8
delta  3  12
eta    4  16
<class 'pandas.core.frame.DataFrame'>

以上代码使用了dataframe.columns为DataFrame赋列名,并且我们看到单独取一列出来,其数据结构显示的是Series,取两列及两列以上的结果仍然是DataFrame。访问特定的元素可以如Series一样使用下标或者是索引:

print df['b'][2]
print df['b']['gamma']
# output
4.0
4.0

若需要选取行,可以使用dataframe.iloc按下标选取,或者使用dataframe.loc按索引选取:

print df.iloc[1]
print df.loc['beta']
# output
a    1
b    2
c    3
d    4
e    5
Name: beta, dtype: float64
a    1
b    2
c    3
d    4
e    5
Name: beta, dtype: float64

选取行还可以使用切片的方式或者是布尔类型的向量:

print df[1:3]
bool_vec = [True, False, True, True, False]
print df[bool_vec]
# output
         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

         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']]
# output
       b   d
beta   2   4
delta  6  12
       b   d
beta   2   4
delta  6  12
       b   d
beta   2   4
delta  6  12
       b   d
beta   2   4
delta  6  12

如果不是需要访问特定行列,而只是某个特殊位置的元素的话,dataframe.at和dataframe.iat是最快的方式,它们分别用于使用索引和下标进行访问:

print df.iat[2, 3]
print df.at['gamma', 'd']
# output
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']]
print "Unwanted result:"
print df.ix[['beta', 2], ['b', 'e']]
print df.ix[[1, 2], ['b', 4]]
# output
10.0
       b   e
delta  6  15
gamma  4  10
       b   e
beta   2   5
gamma  4  10
Unwanted result:
       b   e
beta   2   5
2    NaN NaN
       b   4
beta   2 NaN
gamma  4 NaN

至此,我们已经学会了一些基本操作。


接下来,我们来学习一点实际工作中将会用到的操作,为了看数据方便一点,我们设置一下输出屏幕的宽度,如下:

pd.set_option('display.width', 200)

如果我们需要创建一个以日期为元素的 Series:

dates = pd.date_range('20150101', periods=5)
print dates
# output
DatetimeIndex(['2015-01-01', '2015-01-02', '2015-01-03', '2015-01-04', '2015-01-05'], dtype='datetime64[ns]', freq='D')

将这个日期 Series 作为索引赋给一个 DataFrame:

df = pd.DataFrame(np.random.randn(5,4),index=dates,columns=list('ABCD'))
print df
# output
                   A         B         C         D
2015-01-01 -1.370612 -1.195819  1.575877  1.355894
2015-01-02  0.864163 -0.705902 -1.432597 -0.230507
2015-01-03 -0.441000  0.483336 -1.139024  0.453562
2015-01-04 -0.890501  0.286498 -0.055419  0.190957
2015-01-05  0.814014  0.004511 -0.228120  1.183453

只要是能转换成Series的对象,都可以用于创建DataFrame:

df2 = pd.DataFrame({ 'A' : 1., 'B': pd.Timestamp('20150214'), 'C': pd.Series(1.6,index=list(range(4)),dtype='float64'), 'D' : np.array([4] * 4, dtype='int64'), 'E' : 'hello pandas!' })
print df2
#output
     A          B    C  D              E
0  1.0 2015-02-14  1.6  4  hello pandas!
1  1.0 2015-02-14  1.6  4  hello pandas!
2  1.0 2015-02-14  1.6  4  hello pandas!
3  1.0 2015-02-14  1.6  4  hello pandas!

Reference:

官网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值