title: ‘Pandas系列二:数据结构’
tags:


Pandas的数据结构

Pandas核心的数据结构有两种,表示一维的series和二维的dataframe,二者可以分别看做是在numpy一维数组和二维数组的基础上增加了相应的标签信息。numpy中关于数组的用法基本可以直接应用到这两个数据结构,包括数据创建、切片访问、通函数、广播机制等

Series

它是一种类似于一维数组的对象,是由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。仅由一组数据也可产生简单的Series对象。

初识Pandas系列二-数据结构 - 图1

Series支持的数据类型包括:

  • Python字典
  • ndarray
  • 标量

如何创建Series?

  1. s1 = pd.Series(data=np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])## ndarray
  2. d = {'a': 1, 'b': 2, 'c': 3}
  3. s2 = pd.Series(data=d) ## Python字典
  4. s3 = pd.Series(data=d, index=['a', 'm', 'n']) ## Python字典
  5. s4 = pd.Series(data=5., index=['a', 'b', 'c', 'd', 'e']) ## 标量
  6. index为标签列表

Series的属性操作

理解Series的属性,比如ndim/shape/dtypes/size,分别表示了数据的维数、形状、数据类型和元素个数:

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

输出的结果为:

初识Pandas系列二-数据结构 - 图2

  1. print(s1.ndim) ## 1
  2. print(s1.shape) ## (5,)
  3. print(s1.dtypes) ## float64
  4. print(s1.dtype)## float64
  5. """
  6. 由于pandas允许数据类型是异构的,各列之间可能含有多种不同的数据类型,所以dtype取其复数形式dtypes。
  7. 与此同时,series因为只有一列,所以数据类型自然也就只有一种,pandas为了兼容二者,series的数据类型属性既可以用dtype也可以用dtypes获取;
  8. 而dataframe则只能用dtypes。
  9. """
  10. print(s1.size)## 5
  11. d = {'a': 1, 'b': 2, 'c': 3}
  12. s2 = pd.Series(data=d)
  13. print(s1.array)
  14. """
  15. <PandasArray>
  16. [-0.42215731012740565, -1.302176998745536, 0.8425921792645086,
  17. 0.07607689395042025, 2.845175479227247]
  18. Length: 5, dtype: float64
  19. """
  20. print(s1.to_numpy()) # [-0.42215731 -1.302177 0.84259218 0.07607689 2.84517548]
  21. print(s1.index) # Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
  22. print(s1[0]) # -0.42215731012740565
  23. print(s1['a']) # -0.42215731012740565
  24. print('a' in s1) # True
  25. print(s1.get('f'), np.nan) # None nan
  26. print(s1 + s1)
  27. """
  28. a -0.844315
  29. b -2.604354
  30. c 1.685184
  31. d 0.152154
  32. e 5.690351
  33. dtype: float64
  34. """
  35. print(s1 + s2)
  36. """
  37. a 0.577843
  38. b 0.697823
  39. c 3.842592
  40. d NaN
  41. e NaN
  42. dtype: float64
  43. """

DataFrame

DataFrame是Pandas中的一个表格型的数据结构,包含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型等),DataFrame即有行索引也有列索引,可以被看做是由Series组成的字典。

初识Pandas系列二-数据结构 - 图3

类似于 Excel 、SQL 表,或 Series 对象构成的字典。DataFrame 是最常用的 Pandas 对象,与 Series 一样,DataFrame支持多种类型的输入数据:

如何创建DataFrame?

用 Series 字典或字典生成 DataFrame

可以使用多个Serics生成DataFrame:

初识Pandas系列二-数据结构 - 图4

  1. s1 = pd.Series(data=np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
  2. s2 = pd.Series(data={'a': 1, 'b': 2, 'c': 3})
  3. sd = {'one': s1, 'two': s2}
  4. d1 = pd.DataFrame(data=sd)
  5. print(d1)
  6. """
  7. one two
  8. a -2.210606 1.0
  9. b -0.260349 2.0
  10. c -0.158748 3.0
  11. d 0.047268 NaN
  12. e 1.588751 NaN
  13. """
  14. d2 = pd.DataFrame(sd, index=['d', 'b'])
  15. print(d2)
  16. """
  17. one two
  18. d 0.047268 NaN
  19. b -0.260349 2.0
  20. """
  21. d3 = pd.DataFrame(sd, columns=['two', 'three'])
  22. print(d3)
  23. """
  24. two three
  25. a 1 NaN
  26. b 2 NaN
  27. c 3 NaN
  28. """

用多维数组字典、列表字典生成 DataFrame

  1. sd = {'one': [1, 2, 3, 4], 'two': [5, 6, 7, 8]}
  2. d1 = pd.DataFrame(data=sd)
  3. print(d1)
  4. """
  5. one two
  6. 0 1 5
  7. 1 2 6
  8. 2 3 7
  9. 3 4 8
  10. """
  11. d2 = pd.DataFrame(sd, index=['0', '2', '1', '3'])
  12. print(d2)
  13. """
  14. one two
  15. 0 1 5
  16. 2 2 6
  17. 1 3 7
  18. 3 4 8
  19. """
  20. d3 = pd.DataFrame(sd, columns=['two', 'three'])
  21. print(d3)
  22. """
  23. two three
  24. 0 5 NaN
  25. 1 6 NaN
  26. 2 7 NaN
  27. 3 8 NaN
  28. """

用结构多维数组或记录多维数组生成 DataFrame

  1. data = np.zeros((2,), dtype=[('A', 'i4'), ('B', 'f4'), ('C', 'a10')])
  2. data[:] = [(1, 1., 'test1'), (2, 2., 'test2')]
  3. d1 = pd.DataFrame(data)
  4. print(d2)
  5. """
  6. A B C
  7. 0 1 1.0 b'test1'
  8. 1 2 2.0 b'test2'
  9. """
  10. d2 = pd.DataFrame(data, index=['first', 'second'])
  11. print(d2)
  12. """
  13. A B C
  14. first 1 1.0 b'test1'
  15. second 2 2.0 b'test2'
  16. """
  17. d3 = pd.DataFrame(data, columns=['C', 'A', 'B'])
  18. print(d3)
  19. """
  20. C A B
  21. 0 b'test1' 1 1.0
  22. 1 b'test2' 2 2.0
  23. """

用列表字典生成 DataFrame

  1. sd = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]
  2. d1 = pd.DataFrame(data=sd)
  3. print(d1)
  4. """
  5. a b c
  6. 0 1 2 NaN
  7. 1 5 10 20.0
  8. """
  9. d2 = pd.DataFrame(sd, index=['first', 'second'])
  10. print(d2)
  11. """
  12. a b c
  13. first 1 2 NaN
  14. second 5 10 20.0
  15. """
  16. d3 = pd.DataFrame(sd, columns=['a', 'b'])
  17. print(d3)
  18. """
  19. a b
  20. 0 1 2
  21. 1 5 10
  22. """

用元组字典生成 DataFrame

  1. d1 = pd.DataFrame({('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2},
  2. ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4},
  3. ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6},
  4. ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8},
  5. ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}})
  6. print(d1)
  7. """
  8. a b
  9. b a c a b
  10. A B 1.0 4.0 5.0 8.0 10.0
  11. C 2.0 3.0 6.0 7.0 NaN
  12. D NaN NaN NaN NaN 9.0
  13. """


备选构建器

DataFrame.from_dict

特别注意的是 orient 参数,默认为 columns,把 orient 参数设置为 'index', 即可把字典的键作为行标签。

  1. d1 = pd.DataFrame.from_dict(dict([('A', [1, 2, 3]), ('B', [4, 5, 6])]))
  2. print(d1)
  3. """
  4. A B
  5. 0 1 4
  6. 1 2 5
  7. 2 3 6
  8. """
  9. d2 = pd.DataFrame.from_dict(dict([('A', [1, 2, 3]), ('B', [4, 5, 6])]), orient='index', columns=['a', 'b', 'c'])
  10. print(d2)
  11. """
  12. a b c
  13. A 1 2 3
  14. B 4 5 6
  15. """

DataFrame.from_records

  1. A B
  2. C
  3. b'test1' 1 1.0
  4. b'test2' 2 2.0

DataFrame的属性操作

提取、设置、删除列

  • DataFrame 就像带索引的 Series 字典,提取、设置、删除列的操作与字典类似

用方法链分配新列

  • DataFrame 提供了 assign() 方法,可以利用现有的列创建新列,assign 返回的都是数据副本,原 DataFrame 不变

索引 / 选择

初识Pandas系列二-数据结构 - 图5

数据对齐和运算

  1. sd = {'one': [1, 2, 3, 4], 'two': [5, 6, 7, 8]}
  2. d1 = pd.DataFrame(data=sd)
  3. print(d1)
  4. """
  5. one two
  6. 0 1 5
  7. 1 2 6
  8. 2 3 7
  9. 3 4 8
  10. """
  11. print(d1 + d1)
  12. """
  13. one two
  14. 0 2 10
  15. 1 4 12
  16. 2 6 14
  17. 3 8 16
  18. """
  19. ###布尔运算
  20. d1 = pd.DataFrame({'a': [1, 0, 1], 'b': [0, 1, 1]}, dtype=bool)
  21. d2 = pd.DataFrame({'a': [0, 1, 1], 'b': [1, 1, 0]}, dtype=bool)
  22. print(d1 & d2)
  23. """
  24. a b
  25. 0 False False
  26. 1 False True
  27. 2 True False
  28. """

转置

  1. sd = {'one': [1, 2, 3, 4], 'two': [5, 6, 7, 8]}
  2. d1 = pd.DataFrame(data=sd)
  3. print(d1)
  4. """
  5. one two
  6. 0 1 5
  7. 1 2 6
  8. 2 3 7
  9. 3 4 8
  10. """
  11. print(d1.T)
  12. """
  13. 0 1 2 3
  14. one 1 2 3 4
  15. two 5 6 7 8
  16. """

DataFrame 应用 NumPy 函数

Series 与 DataFrame 可使用 log、exp、sqrt 等多种元素级 NumPy 通用函数(ufunc) ,假设 DataFrame 的数据都是数字。

  1. sd = {'one': [1, 2, 3, 4], 'two': [5, 6, 7, 8]}
  2. d1 = pd.DataFrame(data=sd)
  3. print(d1)
  4. """
  5. one two
  6. 0 1 5
  7. 1 2 6
  8. 2 3 7
  9. 3 4 8
  10. """
  11. print(np.exp(d1))
  12. """
  13. one two
  14. 0 2.718282 148.413159
  15. 1 7.389056 403.428793
  16. 2 20.085537 1096.633158
  17. 3 54.598150 2980.957987
  18. """
  19. print(np.asarray(d1))
  20. """
  21. [[1 5]
  22. [2 6]
  23. [3 7]
  24. [4 8]]
  25. """

Serics和DataFrame 的重构结构属性

  • rename,对标签名重命名,也可以重置index和columns的部分标签列信息,接收标量(用于对标签名重命名)或字典(用于重命名行标签和列标签)
  • reindex,接收一个新的序列与已有标签列匹配,当原标签列中不存在相应信息时,填充NAN或者可选的填充值
  • set_index/reset_index,互为逆操作,前者是将已有的一列信息设置为标签列,而后者是将原标签列归为数据,并重置为默认数字标签
  • set_axis,设置标签列,一次只能设置一列信息,与rename功能相近,但接收参数为一个序列更改全部标签列信息(rename中是接收字典,允许只更改部分信息)
  • rename_axis,重命名标签名,rename中也可实现相同功能