Python Data Analysis Library 或 pandas是为了解决数据分析任务而创建的, 是基于 Numpy 构建的含有更高级数据结构和工具的数据分析包。
类似于 Numpy 的核心是 ndarray,pandas 也是围绕着 Series 和 DataFrame 两个核心数据结构展开的 。Series 和 DataFrame 分别对应于一维的序列和二维的表结构。pandas 约定俗成的导入方法如下:
1
2
|
from
pandas
import
Series,DataFrame
import
pandas as pd
|
Series
Series 可以看做一个定长的有序字典。基本任意的一维数据都可以用来构造 Series 对象:
1
2
3
4
5
6
7
|
>>> s
=
Series([
1
,
2
,
3.0
,
'abc'
])
>>> s
0
1
1
2
2
3
3
abc
dtype:
object
|
虽然 dtype:object
可以包含多种基本数据类型,但总感觉会影响性能的样子,最好还是保持单纯的 dtype。
Series 对象包含两个主要的属性:index 和 values,分别为上例中左右两列。因为传给构造器的是一个列表,所以 index 的值是从 0 起递增的整数,如果传入的是一个类字典的键值对结构,就会生成 index-value 对应的 Series;或者在初始化的时候以关键字参数显式指定一个 index 对象:
1
2
3
4
5
6
7
8
9
10
11
|
>>> s
=
Series(data
=
[
1
,
3
,
5
,
7
],index
=
[
'a'
,
'b'
,
'x'
,
'y'
])
>>> s
a
1
b
3
x
5
y
7
dtype: int64
>>> s.index
Index([
'a'
,
'b'
,
'x'
,
'y'
], dtype
=
'object'
)
>>> s.values
array([
1
,
3
,
5
,
7
], dtype
=
int64)
|
Series 对象的元素会严格依照给出的 index 构建,这意味着:如果 data 参数是有键值对的,那么只有 index 中含有的键会被使用;以及如果 data 中缺少响应的键,即使给出 NaN 值,这个键也会被添加。
注意 Series 的 index 和 values 的元素之间虽然存在对应关系,但这与字典的映射不同。index 和 values 实际仍为互相独立的 ndarray 数组,因此 Series 对象的性能完全 ok。
Series 这种使用键值对的数据结构最大的好处在于,Series 间进行算术运算时,index 会自动对齐。
另外,Series 对象和它的 index 都含有一个 name
属性:
1
2
3
4
5
6
7
8
9
|
>>> s.name
=
'a_series'
>>> s.index.name
=
'the_index'
>>> s
the_index
a
1
b
3
x
5
y
7
Name: a_series, dtype: int64
|
DataFrame
DataFrame 是一个表格型的数据结构,它含有一组有序的列(类似于 index),每列可以是不同的值类型(不像 ndarray 只能有一个 dtype)。基本上可以把 DataFrame 看成是共享同一个 index 的 Series 的集合。
DataFrame 的构造方法与 Series 类似,只不过可以同时接受多条一维数据源,每一条都会成为单独的一列:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
>>> data
=
{
'state'
:[
'Ohino'
,
'Ohino'
,
'Ohino'
,
'Nevada'
,
'Nevada'
],
'year'
:[
2000
,
2001
,
2002
,
2001
,
2002
],
'pop'
:[
1.5
,
1.7
,
3.6
,
2.4
,
2.9
]}
>>> df
=
DataFrame(data)
>>> df
pop state year
0
1.5
Ohino
2000
1
1.7
Ohino
2001
2
3.6
Ohino
2002
3
2.4
Nevada
2001
4
2.9
Nevada
2002
[
5
rows x
3
columns]
|
虽然参数 data 看起来是个字典,但字典的键并非充当 DataFrame 的 index 的角色,而是 Series 的 “name” 属性。这里生成的 index 仍是 “01234”。
较完整的 DataFrame 构造器参数为:DataFrame(data=None,index=None,coloumns=None)
,columns 即 “name”:
1
2
3
4
5
6
7
8
9
10
11
|
>>> df
=
DataFrame(data,index
=
[
'one'
,
'two'
,
'three'
,
'four'
,
'five'
],
columns
=
[
'year'
,
'state'
,
'pop'
,
'debt'
])
>>> df
year state pop debt
one
2000
Ohino
1.5
NaN
two
2001
Ohino
1.7
NaN
three
2002
Ohino
3.6
NaN
four
2001
Nevada
2.4
NaN
five
2002
Nevada
2.9
NaN
[
5
rows x
4
columns]
|
同样缺失值由 NaN 补上。看一下 index、columns 和 索引的类型:
1
2
3
4
5
6
|
>>> df.index
Index([
'one'
,
'two'
,
'three'
,
'four'
,
'five'
], dtype
=
'object'
)
>>> df.columns
Index([
'year'
,
'state'
,
'pop'
,
'debt'
], dtype
=
'object'
)
>>>
type
(df[
'debt'
])
<
class
'pandas.core.series.Series'
>
|
DataFrame 面向行和面向列的操作基本是平衡的,任意抽出一列都是 Series。