核心数据结构

Pandas的核心数据结构有两个,SeriesDataFrame

其中Series是一个带标签的一维同构类型数组。而DataFrame是一个二维表格结构可以包含异构数据列的类型。可以认为DataFrameSeries的容器。

Series

Series是能够保存任何类型数据的一维数组,其轴标签统称为索引。Series可以通过pandas.Series(data, index, dtype, copy)构造函数来创建。构造函数中的各个参数的含义及使用方法如下:

  • dataSeries中存储的数据,可以采用各种格式如Numpy的ndarraylist、常量值等。
  • index,数据的索引列表。索引值必须是唯一和散列的,索引列表的长度与数据的长度要相同。
  • dtype,数据的类型,如果未显式声明类型,则自动推断数据的类型。
  • copy,是否复制数据,默认为False

以下示例从Numpy的ndarray中创建了一个Series

import pandas as pd
import numpy as np
data = np.array(['a', 'b', 'c', 'd'])
s = pd.Series(data, index=[101, 102, 103, 104])
print(s)

字典也可以被用来创建Series,如果没有指定索引,则按照字典中内容的排列顺序取得字典的键来构造索引,如果传递了索引,则按照索引的顺序拉取字典中对应键的值来组建数据。可在交互式解释器中执行以下两段代码以观察区别。

# 不传递索引,使用字典默认顺序
import pandas as pd
data = {'a': 0., 'b': 1., 'c': 2.}
s = pd.Series(data)
print(s)

# 传递索引,使用索引顺序构建数据
import pandas as pd
data = {'a': 0., 'b': 1., 'c': 2.}
s = pd.Series(data, index=['b', 'c', 'd', 'a'])
print(s)

使用常量值来创建Series时,必须提供索引,Series将按照索引的长度,重复常量值来填充数据。例如s = pandas.Series(4, index=[0, 1, 2, 3])

Series中的数据可以使用与列表相似的下标来访问,并且也支持切片。在指定索引之后,还支持使用索引来访问指定位置的数据,但并不局限于获取单一的一个数据。例如:

from pandas import Series
s = Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
# 获取单一元素,返回元素本身
print(s['a'])
# 获取多个元素,返回一个新的Series
print(s[['a', 'c', 'd']])

如果试图获取不存在的索引,Pandas将会抛出KeyError异常。

DataFrame

DataFrame是一个数据以行和列方式排列的二维表格数据结构。在DataFrame中,各列可以是不同的数据类型,并且行列大小都是可变的。DataFrame可以对其中的行和列进行算术运算。DataFrame可以使用构造函数pandas.DataFrame(data, index, columns, dtype, copy)来创建,该函数中大部分参数都与Series相同,其参数的主要含义如下:

  • dataDataFrame中的储存的数据,可以采用ndarray、Series、maplistsdictDataFrame或者是常量值来定义。
  • index,行标签定义,用于定义行索引。其长度要与数据中行总数相同。默认会使用数字序列索引。
  • columns,列标签定义,用于定义列索引。其长度要与数据行中的元素数量相同。默认会使用数字序列索引。
  • dtype,定义每列的数据类型。
  • copy,是否复制数据,默认为False

DataFrame的创建要较Series复杂许多,一般常用列表、字典、Seriesndarrays和DataFrame来创建。

使用列表来创建DataFrame时,列表的每一个元素都对应DataFrame中的一个数据行。例如以下示例。

import pandas as pd
data = [1, 2, 3, 4, 5]
df = pd.DataFrame(data)
print(df)

其输出的结果是下面这个样子。

	0
0	1
1	2
2	3
3	4
4	5

使用比较复杂的二维列表可以创建比较复杂的DataFrame,例如下面这样的表格。

import pandas as pd
data = [['Kate', 95], ['Lily', 90], ['May', 89]]
df = pd.DataFrame(data, columns=['Name', 'Score'])
print(df)

这个示例则会输出以下表格的样子。

	Name	Score
0	Kate	95
1	Lily	90
2	May		89

示例中使用columns参数给数据行中的每个列都建立了标签,并且形成了熟悉的表格样式数据结构。

除此之外,列标签还可以使用字典来设定,下面使用以上数据来看一下使用字典如何创建DataFrame。

import pandas as pd
data = {'Name': ['Kate', 'Lily', 'May'], 'Score': [95, 90, 89]}
df = pd.DataFrame(data)
print(df)

这个示例会得到与前一个示例同样的结果。读者可以自行比较其异同点。使用字典来创建DataFrame还有一种更为复杂的方法,但是在一些情况下可能更为适用,那就是使用字典列表来作为数据源。同样使用以上数据,来看以下使用自点列表作为数据源的示例。

import pandas as pd
data = [{'Name': 'Kate', 'Score': 95}, {'Name': 'Lily', 'Score': 90}, {'Name': 'May', 'Score': 89}]
df = pd.DataFrame(data)
# 或者可以指定更加详细的参数
df = pd.DataFrame(data, index=['1st', '2nd', '3rd'], columns=['Name', 'Score'])
print(df)

前面的所有示例中都没有给定index参数,所以所有数据列的行索引都是采用自增长整型数值的默认索引的,赋予index参数一个与数据行长度相同的列表,可以为每个数据行建立行标签,也就是自定义行索引。这个语法与columns参数的使用是相同的,可参考上例中指定详细参数的用法。

如果Columns参数指定了字典中不存在的键值,那么DataFrame将会将此列的数据记为NaN,表示这里没有任何数字内容。如果数据行之间键值也不相同,那么DataFrame将会采用所有数据行中出现的列的并集作为DataFrame的列标签,并且在每个数据行缺失的列上使用NaN补齐。这里需要注意的是,DataFrame并不是使用None来补齐数据,而是使用NaN

除了可以使用列表的列表、字典列表、字典以外,还可以使用字典的Series、字典的ndarray等相似的数据结构来创建DataFrame,读者可以自行尝试不同的创建DataFrame的方法。

Series类似,DataFrame可以通过dataFrame[column]的格式来访问某个数据列,并且可以对一个不存在的列标签进行赋值来创建一个新列。而删除一个数据列则需要使用.pop(column)函数或者直接使用del dataFrame[column]

对于数据行的操作,DataFrame则提供了.loc(index).iloc(index)两个方法来获取数据列,其中.loc()函数使用DataFrame中实际的行标签来选择行,而.iloc()则是使用数字索引来选择行。对DataFrame使用切片操作是操作数据行,而不是数据列。要向DataFrame中增加一行数据,需要使用.append()函数,删除使用.drop(index)函数。如果DataFrame中有重名的行标签,则会全部被删除掉。

除了使用构造函数来创建DataFrame以外,Pandas还提供了以下用于读取固定格式数据源来直接创建DataFrame的函数(仅包含常用函数,非全部函数)。

函数用于数据源类型
pandas.read_csv().csv格式文件读取数据
pandas.read_clipboard()从剪贴板读取数据
pandas.read_excel()从Excel文件读取数据
pandas.read_gbq()从Google BigQuery读取数据
pandas.read_html()从HTML中的表格中读取数据
pandas.read_json()从JSON字符串中读取数据
pandas.read_pickle()从Python保存的Pickle文件中读取数据
pandas.read_sql()从SQL查询或者数据表中读取数据,支持SQLAlchemy
pandas.read_sql_query()从SQL查询中读取数据,支持SQLAlchemy
pandas.read_sql_table()从数据表中读取数据,支持SQLAlchemy

以上函数的具体使用方法可参考Pandas的文档,这里不再赘述。