1.Pandas对象介绍

Pandas对象介绍

在基础的层面上,Pandas对象可以被认为是NumPy结构化数组的增强版本,在Pandas中行和列是由标签标识的而不是简单的整型索引。如我们在本章的课程中所见,Pandas在基本的数据结构上提供了许多有用的工具,方法和功能,但是所有的这些方法工具要求我们理解这些结构是什么样的。因此,在我们继续前进之前,让我们介绍Pandas的基本数据结构:Series, DataFrameIndex
使用标准的NumPy和Pandas导入来开始我们的代码阶段。

import numpy as np
import pandas as pd

Pandas Series 对象

Pandas Series 是带有索引数据的一维数组。它可以由列表或数组创建,例子如下:

data = pd.Series([0.25, 0.5, 0.75, 1.0])
data
0    0.25
1    0.50
2    0.75
3    1.00
dtype: float64

如我们在输出中所见,Series把一序列值和一序列索引结合在一起。值,索引分别可以通过values和index属性来访问。values的内容是熟悉的NumPy数组。

data.values

array([ 0.25, 0.5 , 0.75, 1. ])

index是一种类似数组的类型 pd.Index,随后会有详尽的讨论。

data.index
RangeIndex(start=0, stop=4, step=1)

就像NumPy数组一样,可以通过python方括号标记里面引用关联的索引来访问对应的数据值。

data[1]
0.5
data[1:3]
1    0.50
2    0.75
dtype: float64

然而,正如我们将看到的,Pandas的Series比它所模拟的一维NumPy更通用,更灵活。

Series作为广义的NumPy 数组

就我们目前所见而言,好像看起来,Series对象基本上可以和NumPy的一维数组可以互换。但关键的不同在于index的表达:NumPy数组使用隐含定义的整型索引来访问数据,而Pandas Series有明确定义的索引与数据像关联。
明确的索引定义给Series对象额外的能力。例如,索引可以不仅是整型,它可以由任何喜欢的类型组成。例如,如果愿意,我们可以使用字符作为索引:

data = pd.Series([0.25, 0.5, 0.75, 1.0],
                 index=['a', 'b', 'c', 'd'])
data
a    0.25
b    0.50
c    0.75
d    1.00
dtype: float64

内容的访问同我们期待的一样:

data['b']
0.5

我们甚至可以使用非连续索引:

data = pd.Series([0.25, 0.5, 0.75, 1.0],
                 index=[2, 5, 3, 7])
data
2    0.25
5    0.50
3    0.75
7    1.00
dtype: float64
data[5]
0.5

Series 作为特殊的字典

用这种方式,你可以认为Pandas Series有点像特殊化的字典。字典是可以映射任意键到任意值集合的结构,而Series是映射类型化的值到类型化值集合的结构。这种类型化是重要的:正如NumPy数组中特定类型的编译代码是它比Python列表的某些操作快一样,Pandas Series的类型信息使它比Python字典的某些操作更高效。

population_dict = {'California': 38332521,
                   'Texas': 26448193,
                   'New York': 19651127,
                   'Florida': 19552860,
                   'Illinois': 12882135}
population = pd.Series(population_dict)
population
California    38332521
Florida       19552860
Illinois      12882135
New York      19651127
Texas         26448193
dtype: int64

默认情况下,Series的索引由排序的键所创建。在这里,典型的字典风格操作也可以被执行:

population['California']
38332521

然而,与字典不同,Series也支持数组风格的操作,例如切片:

population['California':'Illinois']
California    38332521
Florida       19552860
Illinois      12882135
dtype: int64

我们会在Data Indexing and Selection.中讨论Pandas的索引和切片的一些技巧。

构建Series对象

我们已经看到了一些从头开始构建Pandas Series的方法;它们所有都是如下方法的不同版本:

>>> pd.Series(data, index=index)

这里index是可选参数,而data可以是各种不同的实体。
例如,data是列表或NumPy数组,默认情况下,index是整型序列:

pd.Series([2, 4, 6])
0    2
1    4
2    6
dtype: int64

data可以是标量,它被复制与索引的数量相对应:

pd.Series(5, index=[100, 200, 300])
100    5
200    5
300    5
dtype: int64

data可以是字典,默认的index是排序后的字典键值

pd.Series({2:'a', 1:'b', 3:'c'})
1    b
2    a
3    c
dtype: object

在每种情况下,如果期待不同的结果,都可以明确的设置索引:

pd.Series({2:'a', 1:'b', 3:'c'}, index=[3, 2])
3    c
2    a
dtype: object

注意在这个例子中,Series只是显示了明确定义了键值的内容。

Pandas 的DataFrame对象

Pandas中下一个基本结构是DataFrame。如同我们在前面章节讨论的Series对象一样,DataFrame可以被认为是通用化的NumPy数组或特殊化了的python字典。我们现在来看一下这些不同的观点。

DataFrame 作为广义的NumPy 数组

如果将Series类比于带有灵活索引的一维数组,那么DataFrame就类似于带有灵活行索引和列索引的二维数组。正如你可能认为二维数组是整齐排列的一维列序列一样,你可能认为DataFrame是整齐排列的Series对象序列。这里,‘整齐’的意思是指它们共享同样的索引。
作为说明,我们来构造一个新的Series列出前面例子中五个州的面积:

area_dict = {'California': 423967, 'Texas': 695662, 'New York': 141297,
             'Florida': 170312, 'Illinois': 149995}
area = pd.Series(area_dict)
area
California    423967
Florida       170312
Illinois      149995
New York      141297
Texas         695662
dtype: int64

现在我们有area Series以及之前的population Series,我们可以使用字典来构造出一个单独的二维对象用以包那些信息

states = pd.DataFrame({'population': population,
                       'area': area})
states
    area    population
California  423967  38332521
Florida 170312  19552860
Illinois    149995  12882135
New York    141297  19651127
Texas   695662  26448193

与Series对象相似,DataFrame有index属性用来访问索引标识

states.index
Index(['California', 'Florida', 'Illinois', 'New York', 'Texas'], dtype='object')

另外,DataFrame有columns属性,它是一个保存列标识的index对象:

states.columns
Index(['area', 'population'], dtype='object')

因此DataFrame可以被认为是广义的二维NumPy数组,在这里可以使用广义的行索引和列索引来访问数据。

DataFrame作为特殊的字典

类似的,我们也可以认为DataFrame是一种特殊的字典。字典映射键到值,DataFrame映射一个列名字到一个Series类型的列数据。例如,请求‘area’属性返回包含面积信息的Series对象

states['area']
California    423967
Florida       170312
Illinois      149995
New York      141297
Texas         695662
Name: area, dtype: int64

注意这里潜在的困惑点:在一个二维NumPy数组中,data[0]返回的是第一行。对于一个DataFrame,data['col0']将会返回第一列。正因如此,可能认为DataFrame是广义的字典比认为是广义的数组会好些,尽管两种理解方式都是有用的。我们将会探索更多灵活的DataFrame索引方式在Data Indexing and Selection.

构建DataFrame对象

有好几种方式用来构建Pandas DataFrame。这里举几个例子:

通过单独的Series对象生成DataFrame

DateFrame是Series对象的集合,一个单列的DataFrame可以由一个独立的Series对象生成:

pd.DataFrame(population, columns=['population'])
          population
California  38332521
Florida 19552860
Illinois    12882135
New York    19651127
Texas   26448193

通过字典列表生成DataFrame

任何字典列表都能制成DataFrame。我们使用列表解析来创建一些数据:

data = [{'a': i, 'b': 2 * i}
        for i in range(3)]
pd.DataFrame(data)
    a   b
0   0   0
1   1   2
2   2   4

即使字典中的一些键值是缺失的,Pandas也能用NaN(不是数字)来填充

pd.DataFrame([{'a': 1, 'b': 2}, {'b': 3, 'c': 4}])
    a   b   c
0   1.0 2   NaN
1   NaN 3   4.0

通过Serie对象字典生成DataFrame

如我们前面见到的,DataFrame也可以通过Series对象字典来构造:

pd.DataFrame({'population': population,
              'area': area})

通过二维NumPy数组

通过一组二维数组数据,我们可以创建任何指定的列和索引名称的DataFrame。如果选择忽略,列和索引都将是整数:

pd.DataFrame(np.random.rand(3, 2),
             columns=['foo', 'bar'],
             index=['a', 'b', 'c'])

      foo       bar
a   0.865257    0.213169
b   0.442759    0.108267
c   0.047110    0.905718

通过NumPy结构化数组

我们在Structured Data: NumPy's Structured Arrays.会覆盖结构化数组内容。Pandas的DataFrame操作非常像结构数组,并且可以直接从结构数组来创建:

A = np.zeros(3, dtype=[('A', 'i8'), ('B', 'f8')])
A
array([(0, 0.0), (0, 0.0), (0, 0.0)], 
      dtype=[('A', '<i8'), ('B', '<f8')])
pd.DataFrame(A)
    A   B
0   0   0.0
1   0   0.0
2   0   0.0

Pandas Index对象

我们已经看到Series和DataFrame对象都包含一个显式索引,使您可以引用和修改数据。Index对象本身是一个有趣的数据结构,它可以被认为是一个不可变数组或一个有序集合(技术上讲是多集合,因为Index对象可以包含重复的值)。这些观点在Index对象可用的操作中有一些有趣的结果。作为一个简单的例子,让我们从整数列表来构建Index

ind = pd.Index([2, 3, 5, 7, 11])
ind
Int64Index([2, 3, 5, 7, 11], dtype='int64')

index 作为不可变数组

Index在很多方面就像一个数组。例如,我们能使用标准的python索引符号来获取值或切片:

ind[1]
3
ind[::2]
Int64Index([2, 5, 11], dtype='int64')

Index对象也由许多属性与NumPy数组相似:

print(ind.size, ind.shape, ind.ndim, ind.dtype)
5 (5,) 1 int64

Index对象和NumPy数组间的一个区别是索引是不可变的,它们不能通过正常的手段进行修改:

ind[1] = 0
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-34-40e631c82e8a> in <module>()
----> 1 ind[1] = 0


/Users/jakevdp/anaconda/lib/python3.5/site-packages/pandas/indexes/base.py in __setitem__(self, key, value)
   1243 
   1244     def __setitem__(self, key, value):
-> 1245         raise TypeError("Index does not support mutable operations")
   1246 
   1247     def __getitem__(self, key):


TypeError: Index does not support mutable operations

这种不可变性使在多个DataFrames和数组间共享索引更加安全,没有潜在的索引被不经意修改的副作用。

index作为有序集合

Pandas对象被设计为便于如跨数据集的连接那样的操作,这些操作依赖集合计算的许多方面。Index对象遵循许多python内置set数据结构的约定,因此交集,并集,差集和其他组合可以以相似的方法计算:

indA = pd.Index([1, 3, 5, 7, 9])
indB = pd.Index([2, 3, 5, 7, 11])
indA & indB  # intersection 交集
Int64Index([3, 5, 7], dtype='int64')
indA | indB  # union 合并
Int64Index([1, 2, 3, 5, 7, 9, 11], dtype='int64')
indA ^ indB  # symmetric difference 差集
Int64Index([1, 2, 9, 11], dtype='int64')

这些操作也可以通过对象方法来实现,例如indA.intersection(indB).

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容