• Pandas数据结构



    1. Series数据结构

    Series是Pandas的基础数据结构,代表着一列数据,其底层是由Numpy实现的。

    Series的特点:

    1. 所有的元素类型都是一致的;
    2. 如果创建Series时,传入整数列表,默认每个元素的类型都是np.int64;
    3. 如果创建Series时,传入的是小数和整数混合列表,默认每个元素的类型都是np.float64
    4. 如果创建Series时,传入的是其他类型的混合,默认每个元素的类型都是object;
    5. 如果创建Series时,传入的是字符串类型列表,默认每个元素的类型也是object。

    1.1 Series数据类型创建

    利用pd.Series创建一个Series对象,传入的列表作为Series中的数据。

    import pandas as pd
    s = pd.Series(['Banana', 42])
    print(s)
    
    '''
    代码输出:
    0    Banana
    1        42
    dtype: object
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    从代码的执行结果中可以发现,当前的Series的数据类型是object。

    使用·s.values·属性,可以获去Series中的数据,数据的类型是一个Ndarray。

    print(s.values)
    print(type(s.values))
    '''
    代码输出:
    ['Banana' 42]
    
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果使用整数和浮点数的混合列表作为参数,Series的默认类型是np.float64类型。

    print(pd.Series([1,1.2])
    '''
    代码输出:
    0    1.0
    1    1.2
    dtype: float64
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在创建Series对象时,可以指定行索引index(Series代表一列数据)。

    print(pd.Series(['Bill Gates', 'Male'], index=['Name', 'Gender']))
    '''
    代码输出:
    Name      Bill Gates
    Gender          Male
    dtype: object
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意:
    Series代表Pandas数据结构中的列,在Pandas中没有表示行的数据结构。

    1.2 Series的常用属性

    使用pd.read_csv从CSV文件中加载数据,同时指定数据中的id列作为行索引。

    data = pd.read_csv('data/nobel_prizes.csv',index_col='id')
    
    • 1

    使用loc获取数据中的第941行,此时的row就是一个Series对象。

    row = data.loc[941]
    
    • 1

    loc对应的是行索引,如果行索引是从0开始的数字(和行编号一致),此时lociloc作用相同。

    注意:
    由于Pandas中没有对应行的数据结构,所以获得第941行之后,数据行被转换成了列,也就是一个Series

    使用Print查看数据值:

    print(row)
    '''
    代码输出:
    year                                                              2017
    category                                                       physics
    overallMotivation                                                  NaN
    firstname                                                       Rainer
    surname                                                          Weiss
    motivation           "for decisive contributions to the LIGO detect...
    share                                                                2
    Name: 941, dtype: object
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    values

    values属性表示当前Series对象的值,类型是Ndarray:

    print(row.values)
    print(type(row.values))
    '''
    代码输出:
    [2017 'physics' nan 'Rainer' 'Weiss'
     '"for decisive contributions to the LIGO detector and the observation of gravitational waves"'
     2]
    
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    index/keys()

    index属性表示当前Series的行索引:

    print(row.index)
    '''
    代码输出:
    Index(['year', 'category', 'overallMotivation', 'firstname', 'surname',
           'motivation', 'share'],
          dtype='object')
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    keys()方法可以达到同样的效果:

    print(row.keys())
    # 代码结果和row.index完全相同
    
    • 1
    • 2
    shape

    shape属性表示当前Series的行数和列数,是一个元组,由于Series表示一列数据,所以没有列数值:

    print(row.shape)
    '''
    代码输出:
    (7,)
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    T

    T属性表示当前Series的转置,由于Pandas没有行数据结构,所以转置之后和没有转置没什么区别:

    print(row.T)
    '''
    代码输出:
    year                                                              2017
    category                                                       physics
    overallMotivation                                                  NaN
    firstname                                                       Rainer
    surname                                                          Weiss
    motivation           "for decisive contributions to the LIGO detect...
    share                                                                2
    Name: 941, dtype: object
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    loc/iloc

    loc可以通过行列索引获取对应的行列,iloc通过行列序号获取对应的行列:

    print(row.loc['year'])
    print(row.iloc[0])
    '''
    代码输出:
    2017
    2017
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意:
    lociloc的完整使用方法是:

    • loc[行索引,列索引]
    • iloc[行序号,列序号]

    1.3 Series的常用方法

    首先,使用数据.列名的方式获取一列数据,形成一个Series对象:

    share = data.share
    print(share)
    '''
    代码输出:
    id
    941    2
    942    4
    943    4
    944    3
    945    3
         ..
    160    1
    293    1
    569    1
    462    2
    463    2
    Name: share, Length: 923, dtype: int64
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    mean()

    求平均:

    print(share.mean())
    '''
    代码输出:
    1.982665222101842
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    max()/min()

    求最大/小值:

    print(share.max())
    print(share.min())
    '''
    代码输出:
    4
    1
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    var()/std()

    方差和标准差:

    print(share.var())
    print(share.std())
    '''
    代码输出:
    0.8695473357414776
    0.9324952202244672
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    value_counts()

    获取每个值在当前Series对象中的个数:

    print(share.value_counts())
    '''
    代码输出:
    1    347
    2    307
    3    207
    4     62
    Name: share, dtype: int64
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    以上输出的含义是,单个人获得诺贝尔奖项的有347次,两个人获得诺贝尔奖项的有307次,三个人获得诺贝尔奖项的有207次…

    describe()

    计算当前Series对象的各种特征值:

    print(share.describe())
    '''
    代码输出:
    count    923.000000
    mean       1.982665
    std        0.932495
    min        1.000000
    25%        1.000000
    50%        2.000000
    75%        3.000000
    max        4.000000
    Name: share, dtype: float64
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1.4 Series运算

    创建两个Series对象:

    s1 = pd.Series([1,2,3])
    s2 = pd.Series([4,5,6])
    
    • 1
    • 2
    加/减法

    Series执行加法运算时,采用对位相加的方式。

    print(s1 + s2)
    print(s1 - s2)
    '''
    代码输出:
    0    5
    1    7
    2    9
    dtype: int64
    0   -3
    1   -3
    2   -3
    dtype: int64
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    注意:
    对位相加减是基于index值的,也就是说在加减运算执行时,两个index相同的值才算对位。

    如果加减运算时,存在index不对位的情况,就会返回NaN值:

    print(s1 + pd.Series([0,1]))
    '''
    代码输出:
    0    1.0
    1    3.0
    2    NaN
    dtype: float64
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意!如果我们把其中一个Series对象的index倒序排列,依然不影响最终的结果:

    # 倒序排列s2的行索引,再次执行加法,结果不变
    print(s1 + s2.sort_index(ascending=False)
    
    • 1
    • 2
    乘法

    乘法也是对位相乘的:

    print(s1 * s2)
    '''
    代码输出:
    0     4
    1    10
    2    18
    dtype: int64
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2. DataFrame数据结构

    DataFrame是Pandas最重要的数据结构,由一个个的Series组成,可以视为一个二维表:

    2.1 DataFrame数据类型创建

    pd.DataFrame()方法接收一个字典对象作为参数,每个字典的键值对代表一列数据:

    name_list = pd.DataFrame({
        'Name':['Tom','Bob'],
        'Job':['Java','Python'],
        'Age':[28,46]
    })
    print(name_list)
    '''
    代码输出:
      Name     Job  Age
    0  Tom    Java   28
    1  Bob  Python   46
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    我们也可以在创建DataFrame的时候,直接指定索引:

    • 通过index参数指定行索引
    • 通过column参数指定列索引
    print(
        pd.DataFrame(
            data={
                'Job': ['Java', 'Python'],
                'Age': [28, 46]
            },
            index=['Tom', 'Bob'],
            columns=['Job', 'Age']
        )
    )
    '''
    代码输出:
            Job  Age
    Tom    Java   28
    Bob  Python   46
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.2 布尔索引 ★

    首先,加载数据:

    sci = pd.read_csv('data/scientists.csv')
    print(sci)
    '''
    代码输出:
                       Name        Born        Died  Age          Occupation
    0     Rosaline Franklin  1920-07-25  1958-04-16   37             Chemist
    1        William Gosset  1876-06-13  1937-10-16   61        Statistician
    2  Florence Nightingale  1820-05-12  1910-08-13   90               Nurse
    3           Marie Curie  1867-11-07  1934-07-04   66             Chemist
    4         Rachel Carson  1907-05-27  1964-04-14   56           Biologist
    5             John Snow  1813-03-15  1858-06-16   45           Physician
    6           Alan Turing  1912-06-23  1954-06-07   41  Computer Scientist
    7          Johann Gauss  1777-04-30  1855-02-23   77       Mathematician
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    取出数据的前5条,head()方法默认取前五条:

    sci_5 = sci.head()
    
    • 1

    布尔索引的使用方法:

    bool_index = [True, False, False, False, True]
    print(sci_5[bool_index])
    '''
    代码输出:
                    Name        Born        Died  Age Occupation
    0  Rosaline Franklin  1920-07-25  1958-04-16   37    Chemist
    4      Rachel Carson  1907-05-27  1964-04-14   56  Biologist
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    布尔索引中,对应行的值为True就返回,否则就过滤掉。
    布尔索引列表必须和数据长度一致,否则会报错。

    在实际使用过程中,不可能手动的构造一个布尔索引,通常情况下会通过计算直接生成一个布尔列表。
    比如,针对当前数据,我们可以筛选所有年龄大于平均年龄的科学家数据行:

    print(
        sci[sci.Age > sci.Age.mean()]
    )
    '''
    代码输出:
                       Name        Born        Died  Age     Occupation
    1        William Gosset  1876-06-13  1937-10-16   61   Statistician
    2  Florence Nightingale  1820-05-12  1910-08-13   90          Nurse
    3           Marie Curie  1867-11-07  1934-07-04   66        Chemist
    7          Johann Gauss  1777-04-30  1855-02-23   77  Mathematician
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.3 DataFrame的常用属性和方法

    movie = pd.read_csv('data/movie.csv')
    movie.shape 	# 行列数
    movie.ndim		# 维度
    movie.values	# 值
    movie.size		# 元素个数
    len(movie)		# 行数
    movie.count()	# 计算行数,过滤空行(空行不算行数)
    movie.describe()# 对数值列进行特征计算
    
    movie + movie	# 数值直接对位相加,字符串直接拼接
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.4 DataFrame更改操作

    改行索引

    将行索引由数字索引更改为movie_title列:

    movie.set_index('movie_title',inplace=True)
    
    • 1
    解除行索引

    解除当前的行索引,并使用数字索引:

    movie.reset_index()
    
    • 1
    改行列名
    movie.rename(
        index={
            'Avatar':'阿凡达',
            'Star Wars: Episode VII - The Force Awakens':'星期大战7'
        },
        columns={
            'director_name':'导演',
            'color':'颜色'
        },
        inplace=True
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    修改所有的行列
    index = movie.index.to_list()
    index[0] = '阿凡达'
    movie.index = index
    
    • 1
    • 2
    • 3
    增加、删除列
    movie['has_seen'] = 0
    movie['社交媒体点赞数量'] = movie.actor_1_facebook_likes+movie.actor_2_facebook_likes+movie.actor_3_facebook_likes+movie.director_facebook_likes
    
    # 在指定位置插入指定列
    movie.insert(
        loc=0,
        column='利润',
        value=movie.gross - movie.budget
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    删除行列
    movie.drop('社交媒体点赞数量',axis=1)
    # axis=1表示删除列
    movie.drop('阿凡达')
    # 删除行
    
    • 1
    • 2
    • 3
    • 4

    3. Pandas数据导入导出

    # movie.to_pickle('data/movie.pickle')
    # movie.to_csv('data/movie2.csv')
    # movie.to_csv('data/movie2.tsv',sep='\t')
    # movie.to_excel('data/movie.xlsx')
    # movie.read_csv()
    # movie.read_pickle()
    # movie.read_csv(sep='\t')
    # movie.read_excel()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    upp(统一流程平台)项目,如果需要项目章程会怎么写
    Npm使用教程(详细讲解)
    Vue 开发必须知道的 36 个技巧【近1W字】
    ubuntu16 ARM 4G双网卡的上网配置
    Linux 如何排查网络问题
    Django文件上传
    odoo17 web.assets_web.min.js 赏析
    MyBatis初级
    vm虚拟机 ubuntu的NAT模式,配置samba,让win10下 source insigh访问共享
    Mac配置iTerm2、Git等
  • 原文地址:https://blog.csdn.net/weixin_43302112/article/details/133556719