2018-06-15 开胃学习Data系列 - Pandas 基础1

  • 2012 年 Wes McKinney 一本经典的 Python for Data Analysis 由 O'Reilly 出版的。Pandas 参考书 现在有一点过时了 ,他最近宣布新版的新书即将出版 我还是觉得这是一本 瞭解 Pandas 如何作用的必备书 我也欣赏一本更简要的书

  • Learning the Pandas Library 由 Matt Harrison 著作 这不是一本有关资料分析及统计的综合书籍 但如果您只是要学习基本的 Pandas 想要很快的上手

  • Marco Rodriguez 跟 Tim Golden 维护了一个 很棒的部落格称为 Planet Python 您可以到 planetpython.org 这个网站, 订阅 RSS 或者从 推特(Twitter) 的 @PlanetPython 得到最新的文章 里面有很多 Python 资料科学的贡献者 我也强烈建议您订阅 RSS

  • Kyle Polich 运作一个称为 Data Skeptic 的 podcast 它并不是专门讲 Python 但它的制作精良 有很棒的跟这个领域专家座谈 以及 简短的教育课程 大部分的字眼是 有关于机器学习方法 但如果您计画 进一步探索这个学程 这个课程也在其中, 我真的很建议您订阅这个 podcast













The Series Data Structure


  • 传递一个 list 的值来新创一个 Series, 当这麽做时, Pandas 会自动从零开始分配索引 并将该series的名称设置为“None”。

  • 传入一些资料 索引和名称 资料可以是任何东西,类似阵列(array),像list一样。

  • pandas自动的识别了类型 在list中包含的数据,在这裡我们传入string列表, pandas将这类型设定为object。

In [1]:
import pandas as pd
import numpy  as np
In [2]:
animals = ['Tiger', 'Bear', 'Moose','Bear']
pd.Series(animals)

Out[2]:      
0    Tiger
1     Bear
2    Moose
3     Bear
dtype: object
In [3]:
numbers = [1, 2, 3]
pd.Series(numbers)


Out[3]:
0    1
1    2
2    3
dtype: int64
  • 不一定要使用strings。 如果传入整数列表, 可以看见Pandas设定类型为int64。 在Pandas内部储存series的值,使用NumPy程式库的类型阵列(typed array)。 在处理数据时这提供显著的加速相比于传统 Python的list

  • NumPy 和 Pandas 如何处理遗失的资料: 在Python中,有none type以表示资料缺失。

In [4]:
animals = ['Tiger', 'Bear', None]
pd.Series(animals)


Out[4]:
0    Tiger
1     Bear
2     None
dtype: object
In [5]:
numbers = [1, 2, None]
pd.Series(numbers)


Out[5]:
0    1.0
1    2.0
2    NaN
dtype: float64



  • 事实上不能对Nan本身的做相等测试。 因为答案总是错误的。
  • 需要使用特殊功能来测试 '不是一个数字'的存在,例如numpy程式库中的isnan。
In [6]:
np.nan == None

Out[6]:
False
In [7]:
np.nan == np.nan

Out[7]:
False
In [8]:
np.isnan(np.nan)

Out[8]:
True
In [9]:
sports = {'Archery': 'Bhutan',
         'Golf': 'Scotland',
         'Sumo': 'Japan',
         'Taekwondo': 'South Korea'}
s = pd.Series(sports)
s


Out[9]:
Archery           Bhutan
Golf            Scotland
Sumo               Japan
Taekwondo    South Korea
dtype: object

In [10]:
s.index

Out[10]:
Index(['Archery', 'Golf', 'Sumo', 'Taekwondo'], dtype='object')

In [11]:
s = pd.Series(['Tiger', 'Bear', 'Moose'], index=['India', 'America', 'Canada'])
s


Out[11]:
India      Tiger
America     Bear
Canada     Moose
dtype: object
In [12]:
sports = {'Archery': 'Bhutan',
         'Golf': 'Scotland',
         'Sumo': 'Japan',
         'Taekwondo': 'South Korea'}
s = pd.Series(sports, index=['Golf', 'Sumo', 'Hockey'])
s


Out[12]:
Golf      Scotland
Sumo         Japan
Hockey         NaN
dtype: objec
  • series创建完成后, 可以使用index属性获取index对象。
  • 也可以将index的创建与数据分离,通过 将index作为列表,明确地传递给series。

那麽如果index中的值列表 与dictionary中用于创建该系列的keys不对齐

  • pandas会覆盖自动创建index值,仅只用 你提供的所有的index值。
  • 会忽略你的dictionary中所有的keys,当keys不在你的index中,pandas将添加non类型或NaN













Querying a Series


  • Pandas的Series(列表)可以查询,使用索引(index)的位置或索引的标签(label)。

  • 要利用数位位置查询,从零开始,使用 iloc 属性。

  • 要通过索引标签(label)进行查询,可以使用 loc 属性。

  • 以下是维基百科的全国体育赛事数据。假设我们想要列出所有的运动当我们的索引(index),和 国家列表作为值(value)。

sports = {'Archery': 'Bhutan',
          'Golf': 'Scotland',
          'Sumo': 'Japan',
          'Taekwondo': 'South Korea'}
s = pd.Series(sports)
s

>>>
Archery           Bhutan
Golf            Scotland
Sumo               Japan
Taekwondo    South Korea
dtype: object


s.iloc[3]
>>> 'South Korea'

s.loc['Golf']
>>> 'Scotland'

s[3]
>>> 'South Korea'

s['Golf']
>>> 'Scotland'

  • 请记住,iloc和loc不是方法(method),是属性(attribute)。所以不用括号()来查询它们,而是使用方括号[], 我们称之为索引运算符。在Python中, 这是获取(get)和设置(set)一个项目的方法,根据其使用的背景来决定。
  • 这看起来可能有点困惑的,如果你习惯于语言在哪里封装在里面的 属性、变数和性能是常见的,比如在JAVA中。 Pandas试图使我们的程式更具有可读性,并提供一种 智慧语法,使用index操作符直接在series本身。

  • 最后两行指令:例如,如果你传入一个整数参数, 运算子会表现得好像你想要通过iloc属性来查询。如果你传入一个物件(object), 它将认为你想要查询使用根据标签(label)的loc属性。

  • 那么如果你的index是整数列表会发生什么呢?这有点复杂,pandas无法自动确定 你是打算通过索引位置或索引标签进行查询。所以在series本身使用index操作时,你需要小心。而更安全的选择是更加明确,直接使用 iloc或loc属性。
sports = {99: 'Bhutan',
          100: 'Scotland',
          101: 'Japan',
          102: 'South Korea'}
s = pd.Series(sports)


s[0] 
#This won't call s.iloc[0] as one might expect, it generates an error instead
  • 一个典型的程式设计方法,要遍历 该series中的所有项目,并调用一个你感兴趣的运算: 例如,我们可以创建一个浮点值的数据组(dataframe)。让我们把这些看作是不同产品的价格。我们可以写一个小的例行程序码,遍历的所有 series中的项目,并将它们加一起以获得总数。

  • Pandas和基础的NumPy程式库支持一个称为 向量化 vectorization.

  • Vectorization与NumPy库中的大部分功能一起使用, 包括sum函数。

  • 调用np.sum 并传入一个可遍历迭代的项目。在这里,我们的pandas series。

s = pd.Series([100.00, 120.00, 101.00, 3.00])
s

>>>
0    100.0
1    120.0
2    101.0
3      3.0
dtype: float64

total = 0
for item in s:
    total+=item
print(total)
>>> 324.0

total = np.sum(s)
print(total)
>>> 324.0

现在这两种方法产生相同的值,但是哪一种是确实更快吗?
首先,设置一个大系列的随机(random)数字。

  • 神奇功能以百分比符号%开头。如果我们打入这个标志%,然后按Tab键, 我们可以看到可用的魔术函数的列表。你也可以编写自己的魔术函数 但这不过是本课程的范围之外。我们实际上会

  • 使用所谓的细胞(cellular)魔术函数 -- 以两个百分比的符号开始, 并修改或包装当前Jupyter单元中的程式。

** 要使用的函数称为timeit。你可能已经从名称猜到了,此函数会运行我们的程式几次来确定,平均运行时间。


#this creates a big series of random numbers
s = pd.Series(np.random.randint(0,1000,10000))
s.head()


%%timeit -n 100
summary = 0
for item in s:
    summary+=item
>>> 100 loops, best of 3: 1.87 ms per loop

%%timeit -n 100
summary = np.sum(s)
>>>100 loops, best of 3: 107 µs per loop
  • 在pandas和NumPy的相关的功能称为广播(broadcasting)。通过broadcasting,你可以对series中的每个值应用操作, 更改series。
  • 例如,如果我们想要对每个随机变数增加2, 我们可以使用+=运算符号直接在列表对像上快速地执行。在这里,我只需要使用head运算印出前五项 首先,我想要先来介绍这门课的四位讲师
  • 做这的样程序方式是,遍历所有的 列表中的项目和直接增加它的数值。很快的提一下, Pandas确实支持遍历迭代列表项目,很类似于dictionary, 让你容易地把数值分拆开。但如果你发现自己反覆遍历一列表, 你应该质疑你做的方式是否是尽可能最好的。
%%timeit -n 10
s = pd.Series(np.random.randint(0,1000,10000))
for label, value in s.iteritems():
    s.loc[label]= value+2
>>>
10 loops, best of 3: 1.65 s per loop

%%timeit -n 10
s = pd.Series(np.random.randint(0,1000,10000))
s+=2
>>>​
10 loops, best of 3: 514 µs per loop
  • 最后一点要注意的,在使用索引运算来存取列表资料。 .loc属性(attribute) 不仅可以修改数据, 还可以添加新数据。如果作为索引传入的值不存在,则它会添加一个新条目。请记住,指数可以有混合类型。虽然重要的是,要注意在下面的类型是什么, Pandas会根据需要,自动更改基本的NumPy类型。
s = pd.Series([1, 2, 3])
s.loc['Animal'] = 'Bears'
s
>>>
0             1
1             2
2             3
Animal    Bears
dtype: object
original_sports = pd.Series({'Archery': 'Bhutan',
                             'Golf': 'Scotland',
                             'Sumo': 'Japan',
                             'Taekwondo': 'South Korea'})
cricket_loving_countries = pd.Series(['Australia',
                                      'Barbados',
                                      'Pakistan',
                                      'England'], 
                                   index=['Cricket',
                                          'Cricket',
                                          'Cricket',
                                          'Cricket'])
all_countries = original_sports.append(cricket_loving_countries)

original_sports
Archery           Bhutan
Golf            Scotland
Sumo               Japan
Taekwondo    South Korea
dtype: object

cricket_loving_countries
Cricket    Australia
Cricket     Barbados
Cricket     Pakistan
Cricket      England
dtype: object

all_countries
Archery           Bhutan
Golf            Scotland
Sumo               Japan
Taekwondo    South Korea
Cricket        Australia
Cricket         Barbados
Cricket         Pakistan
Cricket          England
dtype: object

all_countries.loc['Cricket']
Cricket    Australia
Cricket     Barbados
Cricket     Pakistan
Cricket      England
dtype: object
  • 我们回到我们原来的运动列表。可以创建一个带有多个条目的新列表,用 板球索引,然后使用append将它们放在一起。使用append时,有几个重要的注意事项。首先,Pandas将采取你的列表, 并尝试推断使用最好的数据类型。在这个例子中,一切都是字符(string),所以这里没有问题。
  • 其次,append方法实际上并没有改变底层的列表。而是返回一个由两个附加在一起组成的新列表。我们可以回溯并列印原始列表值, 看到它们没有改变。
  • 这是实际上的一个重大问题 新的Pandas使用者,之前习惯了物件(objects)在原处更改。所以要当心了,不只是append,还有其他的Pandas函数功能。

  • 最后,我们看到,当我们查询附加在一起的列表,用板球 作为国家运动的,我们不是得到一个单一的值,而是一个列表。这实际上是很常见的。













The DataFrame Data Structure


  • DataFrame数据结构是Pandas的核心。

  • DataFrame在概念上是一个二维列表(series)对象, 其中有一个索引(index)和多列内容,每列(column)都有一个标签(label)。事实上,列(column)和行(row)之间的区别 实际上只是一个概念上的区别。可以将DataFrame本身视为简单的双轴有标签的阵列。

  • 可以以许多不同的方式创建一个DataFrame。例如,你可以使用一组列表(series), 其中每个列表代表一行数据。或者你可以使用一组字典(dictionary), 其中每个字典都代表一行数据。
purchase_1 = pd.Series({'Name': 'Chris',
                        'Item Purchased': 'Dog Food',
                        'Cost': 22.50})
purchase_2 = pd.Series({'Name': 'Kevyn',
                        'Item Purchased': 'Kitty Litter',
                        'Cost': 2.50})
purchase_3 = pd.Series({'Name': 'Vinod',
                        'Item Purchased': 'Bird Seed',
                        'Cost': 5.00})
df = pd.DataFrame([purchase_1, purchase_2, purchase_3], index=['Store 1', 'Store 1', 'Store 2'])
df.head()

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