Skip to content

Pandas 数据结构

Pandas 中一共有三种数据结构,分别为:Series、DataFrame 和 MultiIndex(老版本中叫 Panel)。

其中 Series 是一维数据结构,DataFrame 是二维的表格型数据结构,MultiIndex 是三维的数据结构。

Series

Series 是一个类似于一维数组的数据结构,它能够保存任何类型的数据,比如整数、字符串、浮点数等,主要由一组数据和与之相关的索引两部分构成。

Series 的创建

python
# 导入 pandas
import pandas as pd

pd.Series(data=None, index=None, dtype=None)

参数:

  • data:传入的数据,可以是 ndarray、list 等
  • index:索引,必须是唯一的,且与数据的长度相等。如果没有传入索引参数,则默认会自动创建一个从 0-N 的整数索引。
  • dtype:数据的类型

通过已有数据创建

  • 指定内容,默认索引
python
ser2 = pd.Series(np.arange(5))
print('ser2:\n', ser2)

# 运行结果
0    0
1    1
2    2
3    3
4    4
dtype: int64

指定行索引名

示例代码:

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

# 运行结果:
a    0
b    1
c    2
d    3
e    4
dtype: int64

通过字典数据创建

python
ser4 = pd.Series({'red': 100, 'blue': 200, 'green': 500, 'yellow': 1000})
ser4

# 运行结果
blue       200
green      500
red        100
yellow    1000
dtype: int64

Series 的属性

为了更方便地操作 Series 对象中的索引和数据,Series 中提供了两个属性 index 和 values

  • index

    python
    print('ser4.index:\n', ser4.index)
    
    # 结果
    Index(['blue', 'green', 'red', 'yellow'], dtype='object')
  • values

    python
    print('ser4.values:\n', ser4.values)
    
    # 结果
    array([ 200,  500,  100, 1000])
  • 也可以使用索引来获取数据:

    python
    print('ser4[2]:\n', ser4.iloc[2])
    
    # 结果
    100

DataFrame

DataFrame 是一个类似于二维数组或表格(如 excel)的对象,既有行索引,又有列索引

  • 行索引,表明不同行,横向索引,叫 index0 轴,axis=0
  • 列索引,表名不同列,纵向索引,叫 columns1 轴,axis=1

DataFrame 的创建

python
# 导入 pandas
import pandas as pd

df1 = pd.DataFrame(data=None, index=None, columns=None)
print('df1:\n', df1)

参数:

  • index:行标签。如果没有传入索引参数,则默认会自动创建一个从 0-N 的整数索引。
  • columns:列标签。如果没有传入索引参数,则默认会自动创建一个从 0-N 的整数索引。

通过已有数据创建

举例一:

python
import numpy as np
import pandas as pd

df2 = pd.DataFrame(np.random.randn(2, 3))
print(df2)

""" 输出结果
          0         1         2
0  1.733204 -0.065923 -2.090919
1  1.775286 -0.154595  0.516878
"""

回忆咱们在前面直接使用 np 创建的数组显示方式,比较两者的区别。

举例二:创建学生成绩表

python
# "语文", "数学", "英语", "政治", "体育"
score = [
    [92, 55, 78, 50, 50],
    [71, 76, 50, 48, 96],
    [45, 84, 78, 51, 68],
    [81, 91, 56, 54, 76],
    [86, 66, 77, 67, 95],
    [46, 86, 56, 61, 99],
    [46, 95, 44, 46, 56],
    [80, 50, 45, 65, 57],
    [41, 93, 90, 41, 97],
    [65, 83, 57, 57, 40]
]

# 生成 10 名同学,5 门功课的数据
df3 = pd.DataFrame(score)
print('df3:\n', df3)

""" 输出结果
df3:
    0   1   2   3   4
0  92  55  78  50  50
1  71  76  50  48  96
2  45  84  78  51  68
3  81  91  56  54  76
4  86  66  77  67  95
5  46  86  56  61  99
6  46  95  44  46  56
7  80  50  45  65  57
8  41  93  90  41  97
9  65  83  57  57  40
"""

但是这样的数据形式很难看到存储的是什么的样的数据,可读性比较差!!

问题:如何让数据更有意义的显示

给分数数据增加行列索引,显示效果更佳

增加行、列索引

python
"""增加行列索引"""
# 构造行索引序列
subjects = ["语文", "数学", "英语", "政治", "体育"]

# 构造列索引序列
stu = ['同学' + str(i) for i in range(len(score))]

# 添加行索引
students = pd.DataFrame(score, columns=subjects, index=stu)
print('students:\n', students)

"""输出结果
students:
      语文  数学  英语  政治  体育
同学 0  92    55   78    50    50
同学 1  71    76   50    48    96
同学 2  45    84   78    51    68
同学 3  81    91   56    54    76
同学 4  86    66   77    67    95
同学 5  46    86   56    61    99
同学 6  46    95   44    46    56
同学 7  80    50   45    65    57
同学 8  41    93   90    41    97
同学 9  65    83   57    57    40
"""

DataFrame 的属性

  • shape

    python
    print('students.shape:\t', students.shape)
    
    # 结果
    students.shape:	 (10, 5)
  • index

    DataFrame 的行索引列表

    python
    print('students.index:\t', students.index)
    
    # 结果
    students.index:	 Index(['同学 0', '同学 1', '同学 2', '同学 3', '同学 4', '同学 5', '同学 6', '同学 7', '同学 8', '同学 9'], dtype='object')
  • columns

    DataFrame 的列索引列表

    python
    print('students.columns:\t', students.columns)
    
    # 结果
    students.columns:	 Index(['语文', '数学', '英语', '政治', '体育'], dtype='object')
  • values

    直接获取其中 array 的值

    python
    print('students.values:\n', students.values)
    
    # 结果
    students.values:
     [[92 55 78 50 50]
     [71 76 50 48 96]
     [45 84 78 51 68]
     [81 91 56 54 76]
     [86 66 77 67 95]
     [46 86 56 61 99]
     [46 95 44 46 56]
     [80 50 45 65 57]
     [41 93 90 41 97]
     [65 83 57 57 40]]
  • T

    转置

    python
    print('students.T\n', students.T)
    """ 输出结果
    students.T:
             同学 0  同学 1  同学 2  同学 3  同学 4  同学 5  同学 6  同学 7  同学 8  同学 9
       语文   92     71     45     81    86    46     46    80     41    65
       数学   55     76     84     91    66    86     95    50     93    83
       英语   78     50     78     56    77    56     44    45     90    57
       政治   50     48     51     54    67    61     46    65     41    57
       体育   50     96     68     76    95    99     56    57     97    40
    """
  • head(5):显示前 5 行内容

    如果不补充参数,默认 5 行。填入参数 N 则显示前 N 行

    python
    print('students.head(5):\n', students.head(5))
    """ 输出结果
    students.head(5):
          语文  数学  英语  政治  体育
    同学 0  92   55    78   50    50
    同学 1  71   76    50   48    96
    同学 2  45   84    78   51    68
    同学 3  81   91    56   54    76
    同学 4  86   66    77   67    95
    """
  • tail(5): 显示后 5 行内容

    如果不补充参数,默认 5 行。填入参数 N 则显示后 N 行

    python
    print('students.tail(5):\n', students.tail(5))
    """
    students.tail(5):
          语文  数学  英语  政治  体育
    同学 5  46   86    56   61    99
    同学 6  46   95    44   46    56
    同学 7  80   50    45   65    57
    同学 8  41   93    90   41    97
    同学 9  65   83    57   57    40
    """

DataFrame 索引

需求:

image-20190624095757620

修改行列索引值

python
stu = ["学生_" + str(i) for i in range(score_df.shape[0])]

# 必须整体全部修改
data.index = stu

注意:以下修改方式是错误的

python
# 错误修改方式
data.index[3] = '学生_3'

重设索引

reset_index(drop=False)

  • 设置新的下标索引
  • drop: 默认为 False,不删除原来索引,如果为 True, 删除原来的索引值
python
# 重置索引,drop=False

data.reset_index()

image-20190624100048415

python
# 重置索引,drop=True

data.reset_index(drop=True)

以某列值设置为新的索引

set_index(keys, drop=True)

  • keys : 列索引名成或者列索引名称的列表
  • drop : boolean, default True. 当做新的索引,删除原来的列

设置新索引案例

  1. 创建

    python
    df = pd.DataFrame({'month': [1, 4, 7, 10],
                        'year': [2012, 2014, 2013, 2014],
                        'sale':[55, 40, 84, 31]})
    
    # 输出
       month  sale  year
    0  1      55    2012
    1  4      40    2014
    2  7      84    2013
    3  10     31    2014
  2. 以月份设置新的索引

    python
    df.set_index('month')
    
    # 输出
           sale  year
    month
    1      55    2012
    4      40    2014
    7      84    2013
    10     31    2014
  3. 设置多个索引,以年和月份

    python
    df = df.set_index(['year', 'month'])
    df
    
    # 输出
                sale
    year  month
    2012  1     55
    2014  4     40
    2013  7     84
    2014  10    31

注:通过刚才的设置,这样 DataFrame 就变成了一个具有 MultiIndex 的 DataFrame。

索引对象

Index 索引

  1. Series 和 DataFrame 中的索引都是 Index 对象

    示例代码:

    python
    df = pd.DataFrame({'month': [1, 4, 7, 10],
                       'year': [2012, 2014, 2013, 2014],
                       'sale': [55, 40, 84, 31]})
    se = pd.Series(np.arange(10))
    df.index, se.index

    运行结果:

    (RangeIndex(start=0, stop=4, step=1), RangeIndex(start=0, stop=10, step=1))
  2. 索引对象不可变,保证了数据的安全

    示例代码:

    python
    # 索引对象不可变
    df.index[0] = 2

    运行结果:

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-23-7f40a356d7d1> in <module>()
          1 # 索引对象不可变
    ----> 2 df_obj2.index[0] = 2
    
    /Users/Power/anaconda/lib/python3.6/site-packages/pandas/indexes/base.py in __setitem__(self, key, value)
       1402
       1403     def __setitem__(self, key, value):
    -> 1404         raise TypeError("Index does not support mutable operations")
       1405
       1406     def __getitem__(self, key):
    
    TypeError: Index does not support mutable operations

索引小案例

python
# %%
import pandas as pd

df = pd.DataFrame({
    'rank': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'name': ['七星龙渊', '太阿', '干将', '承影', '湛泸', '纯钧', '莫邪', '赤霄', '轩辕夏禹剑', '鱼肠'],
    'alias': ['仁道之剑', '勇绝之剑', '圣道之剑', '威道之剑', '尊贵无双之剑', '帝道之剑', '挚情之剑', '挚情之剑',
              '精致优雅之剑', '诚信高洁之剑'],
    'nickname': ['乌剑', '白剑', '紫剑', '红剑', '红木剑', '金剑', '银剑', '青剑', '青剑', '黄剑']
})
print(df)

# %%
"""重置索引"""
# 以某列值设置为新的索引
df2 = df.set_index('rank')
print(df2)
print(df2.index)

# %%
# 重置索引
df2.reset_index()
print('df2.reset_index():\n', df2.reset_index())
# 重置索引并且删除之前的索引
print('df2.reset_index(drop=True):\n', df2.reset_index(drop=True))
# %%
"""修改行列索引值"""

df2.index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
print(df2)
# %%
"""复合索引"""
df3 = df.set_index(['rank', 'nickname'])
print(df3)

小结

  • pandas 的优势【了解】
    • 增强图表可读性
    • 便捷的数据处理能力
    • 读取文件方便
    • 封装了 Matplotlib、Numpy 的画图和计算
  • series【知道】
    • 创建
      • pd.Series([], index=[])
      • pd.Series({})
    • 属性
      • 对象 .index
      • 对象 .values
  • DataFrame【掌握】
    • 创建
      • pd.DataFrame(data=None, index=None, columns=None)
    • 属性
      • shape -- 形状
      • index -- 行索引
      • columns -- 列索引
      • values -- 查看值
      • T -- 转置
      • head() -- 查看头部内容
      • tail() -- 查看尾部内容
    • DataFrame 索引
      • 修改的时候,需要进行全局修改
      • 对象 .reset_index()
      • 对象 .set_index(keys)