美文网首页我爱编程
2018-06-15 开胃学习Data系列 - Pandas 基

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

作者: Kaiweio | 来源:发表于2018-06-16 11:28 被阅读0次
    • 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)也包括在输出中。

    相关文章

      网友评论

        本文标题:2018-06-15 开胃学习Data系列 - Pandas 基

        本文链接:https://www.haomeiwen.com/subject/nnsveftx.html