• 小白学 Python 数据分析(3):Pandas (二)数据结构 Series


    在家为国家做贡献太无聊,不如跟我一起学点 Python

    顺便问一下,你们都喜欢什么什么样的文章封面图,老用这一张感觉有点丑

    人生苦短,我用 Python

    前文传送门:

    小白学 Python 数据分析(1):数据分析基础

    小白学 Python 数据分析(2):Pandas (一)概述

    引言

    先介绍下 Pandas 的数据结构,毕竟数据结构是万物的基础。

    Pandas 有两种主要的数据结构: Series 和 DataFrame ,本文就先介绍第一种 Series 。

    模块导入

    首先我们在代码中引入 Pandas 和 Numpy ,如下:

    import numpy as np
    import pandas as pd
    

    Series

    Series 可以简单的理解为一维数组,可以存储整数、浮点数、字符串、Python 对象等类型的数据。

    这个概念有点像 Java 中的集合。

    如果无法理解的话,那么可以看下面这个图(Excel 简单画画,灵魂画手登场):

    这里的 data 可以是上面提到的那些数据类型,并不仅限于图中的整数。

    如果 index 的值未指定,那么将会自动的创建数值类型的索引,从 0 开始,例如:0 , 1 , 2, 3 ... len(data) - 1 。

    创建一个 Series ,这里我们可以使用 pd.Series 函数来创建,如下:

    s = pd.Series(np.random.rand(5), index=['a', 'b', 'c', 'd', 'e'])
    print(s)
    print(s.index)
    
    s1 = pd.Series(np.random.randn(5))
    print(s1)
    

    结果如下:

    a    0.218164
    b    0.153201
    c    0.572437
    d    0.142784
    e    0.710664
    dtype: float64
    Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
    0    0.255452
    1    1.354357
    2    2.092490
    3    0.353899
    4    1.692989
    dtype: float64
    

    从上面我们可以看到,如果我们手动指定了索引,那么将会按照我们指定的索引进行创建,如果没有指定会直接使用数值索引。

    注意: 如果我们手动指定索引,索引的长度必须与数据的长度一致。如果不一致,将会抛出 ValueError 的异常,如下:

    s = pd.Series(np.random.rand(6), index=['a', 'b', 'c', 'd', 'e'])
    

    异常部分内容:

    ValueError: Length of passed values is 6, index implies 5
    

    字典实例化

    Series 是可以使用字典进行实例化的,示例如下:

    d = {'b': 1, 'a': 0, 'c': 2}
    s2 = pd.Series(d)
    print(s2)
    

    结果如下:

    b    1
    a    0
    c    2
    dtype: int64
    

    注意: 当我们使用的 data 为字典的时候,且未设置 index 参数时,如果 Python 版本 >= 3.6 且 Pandas 版本 >= 0.23, Series 按字典的插入顺序排序索引。Python < 3.6 或 Pandas < 0.23,且未设置 index 参数时, Series 按字母顺序排序字典的键(key)列表。

    在上面的这个示例中,如果当前的环境 Python < 3.6 或 Pandas < 0.23, Series 将会按照字母的顺序进行排序,而不是当前字典的顺序,输出的结果将会是 ['a', 'b', 'c']

    同时,如果我们在使用字典做 data 的时候,同样可以设置索引,这样将会按照索引来提取 data 中对应的值,如果索引在 data 中无对应,将会使用 NaN 来表示缺失的数据,示例如下:

    s3 = pd.Series(d, index=['b', 'c', 'd', 'a'])
    print(s3)
    

    结果如下:

    b    1.0
    c    2.0
    d    NaN
    a    0.0
    dtype: float64
    

    标量值实例化

    data 还支持标量值进行实例化,当 data 是标量值的时候,实例化 Series 的时候必须提供索引, Series 将会按照索引的长度重复这个标量值,如下:

    s4 = pd.Series(5., index=['a', 'b', 'c', 'd', 'e'])
    print(s4)
    

    结果如下:

    a    5.0
    b    5.0
    c    5.0
    d    5.0
    e    5.0
    dtype: float64
    

    基于索引的操作方式

    print(s[0])
    print(s[:3])
    print(s[s > s.median()])
    print(s[[4, 3, 1]])
    

    结果如下:

    0.481205137399224
    
    a    0.481205
    b    0.045604
    c    0.108321
    dtype: float64
    
    d    0.495208
    e    0.817171
    dtype: float64
    
    e    0.817171
    d    0.495208
    b    0.045604
    dtype: float64
    

    同时, Series 还支持通过索引标签进行设置值或者是取值,如下:

    print(s['a'])
    s['e'] = 12.
    print(s)
    

    结果如下:

    0.481205137399224
    
    a     0.481205
    b     0.045604
    c     0.108321
    d     0.495208
    e    12.000000
    dtype: float64
    

    如果直接使用 Series 中没有的索引标签,会抛出 KeyError 异常:

    # 抛出 KeyError 异常
    # print(s['f'])
    

    我们可以通过 in 来判断当前的 Series 中有没有含有索引标签,如下:

    print('e' in s)
    print('f' in s)
    

    结果如下:

    True
    False
    

    可以通过 get 这个方法获取 Series 没有的索引标签,同时可以设置返回的默认值:

    print(s.get('f'))
    print(s.get('f', np.nan))
    

    结果如下:

    None
    nan
    

    常用方法

    # 打印 e 的幂次方, e 是一个常数为 2.71828
    print (np.exp(s))
    # 打印 s 里每个元素的开方
    print (np.sqrt(s))
    print(s.dtype)
    print(s.array)
    print(s.to_numpy())
    

    结果如下:

    a    1.618023
    b    1.046659
    c    1.114406
    d    1.640840
    e    2.264085
    dtype: float64
    
    a    0.693690
    b    0.213550
    c    0.329122
    d    0.703711
    e    0.903975
    dtype: float64
    
    float64
    
    <PandasArray>
    [  0.481205137399224, 0.04560362121419126, 0.10832121726528887,
     0.49520848929233285,  0.8171705710254773]
    Length: 5, dtype: float64
    
    [0.48120514 0.04560362 0.10832122 0.49520849 0.81717057]
    

    从上面的示例中可以看到,当使用 Series 做一些算数运算的时候,是不需要循环 Series 中每个值的。

    注意: Series 之间的操作会自动基于标签对齐数据。

    print(s[1:] + s[:-1])
    

    结果如下:

    a         NaN
    b    0.091207
    c    0.216642
    d    0.990417
    e         NaN
    dtype: float64
    

    操作未对齐索引的 Series, 其计算结果是所有涉及索引的并集。如果在 Series 里找不到标签,运算结果标记为 NaN,即缺失值。

    名称属性

    Series 支持 name 属性,我们可以给我们自己定义的 Series 起一个自己喜欢的名字:

    s5 = pd.Series(np.random.randn(5), name='my_series')
    print(s5)
    print(s5.name)
    print(id(s5))
    

    结果如下:

    0    0.491450
    1    0.939965
    2    0.868437
    3   -0.099575
    4    1.866875
    Name: my_series, dtype: float64
    
    my_series
    
    1492397351368
    

    这里小编顺手使用 id 方法打印一下 s5 的内存地址。

    同样, Series 为我们提供了重命名的方法 rename()

    # 重命名 series
    s6 = s5.rename("my_series_different")
    print(id(s6))
    

    结果如下:

    1492397351368
    0    0.491450
    1    0.939965
    2    0.868437
    3   -0.099575
    4    1.866875
    Name: my_series_different, dtype: float64
    
    1492400065800
    

    对比上下两个 s5 和 s6 可以看到,这两个 Series 具有相同的 data 内容, name 属性并不相同。

    但是,有一点要注意的是: s5 和 s6 是两个不同的对象,这里打印的内存地址不同也说明了这一点,这里实际上并不是将 s5 的 name 修改了一下,而是新建了一个新的对象并使用了新的 name 属性。

    示例代码

    老规矩,所有的示例代码都会上传至代码管理仓库 Github 和 Gitee 上,方便大家取用。

    示例代码-Github

    示例代码-Gitee

    参考

    https://www.pypandas.cn/docs/getting_started/dsintro.html

  • 相关阅读:
    浅谈均值、方差、标准差、协方差的概念及意义
    数据库设计的基本步骤
    VS添加lib库
    Android activity_main.xml删除边缘距离,充满屏幕
    Android 设置旋转朝向
    WebStorm注册码
    VS禁止特定警告
    VS 高亮显示不带后缀的C++头文件
    VS2010设置C++包含目录和库目录
    读取STL模型
  • 原文地址:https://www.cnblogs.com/babycomeon/p/12316511.html
Copyright © 2020-2023  润新知