- 4.1 The NumPy ndarray 多维数组对象
- 4.2 Universal Functions 通用函数
- 4.3 Array-Oriented Programming with Arrays 数组导向编程
- 5.1 Introduction to pandas Data Structures pandas 的数据结构
- 5.2 Essential Functionality 主要功能
- 5.3 Summarizing and Computing Descriptive Statistics 汇总和描述性统计
- 7.1 Handling Missing Data 处理缺失数据
- 7.2 Data Transformation 数据变换
- 7.3 String Manipulation 字符串处理
- 11.1 Date and Time Data Types and Tools 日期和时间数据类型及其工具
- 11.2 Time Series Basics 时间序列基础
- 11.3 Date Ranges, Frequencies, and Shifting 日期范围,频度,和位移
- 12.1 Categorical Data 类别数据
- 14.1 USA.gov Data from Bitly USA.gov 数据集
- 14.2 MovieLens 1M Dataset MovieLens 1M 数据集
- 14.3 US Baby Names 1880–2010 1880年至2010年美国婴儿姓名
5.1 Introduction to pandas Data Structures pandas 的数据结构
CHAPTER 5 Getting Started with pandas
这一节终于要开始讲 pandas 了。闲话不说,直接开始正题。之后的笔记里,这样导入 pandas:
import pandas as pd
另外可以导入 Series 和 DataFrame,因为这两个经常被用到:
from pandas import Series, DataFrame
5.1 Introduction to pandas Data Structures
数据结构其实就是 Series 和 DataFrame。
1 Series
这里 series 我就不翻译成序列了,因为之前的所有笔记里,我都是把 sequence 翻译成序列的。
series 是一个像数组一样的一维序列,并伴有一个数组表示 label,叫做 index。创建一个 series 的方法也很简单:
obj = pd.Series([4, 7, -5, 3]) obj
0 4 1 7 2 -5 3 3 dtype: int64
可以看到,左边表示 index,右边表示对应的 value。可以通过 value 和 index 属性查看:
obj.values
array([ 4, 7, -5, 3])
obj.index # like range(4)
RangeIndex(start=0, stop=4, step=1)
当然我们也可以自己指定 index 的 label:
obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
obj2
d 4 b 7 a -5 c 3 dtype: int64
obj2.index
Index(['d', 'b', 'a', 'c'], dtype='object')
可以用 index 的 label 来选择:
obj2['a']
-5
obj2['d'] = 6
obj2[['c', 'a', 'd']]
c 3 a -5 d 6 dtype: int64
这里['c', 'a', 'd']其实被当做了索引,尽管这个索引是用 string 构成的。
使用 numpy 函数或类似的操作,会保留 index-value 的关系:
obj2[obj2 > 0]
d 6 b 7 c 3 dtype: int64
obj2 * 2
d 12 b 14 a -10 c 6 dtype: int64
import numpy as np np.exp(obj2)
d 403.428793 b 1096.633158 a 0.006738 c 20.085537 dtype: float64
另一种看待 series 的方法,它是一个长度固定,有顺序的 dict,从 index 映射到 value。在很多场景下,可以当做 dict 来用:
'b' in obj2
True
'e' in obj2
False
还可以直接用现有的 dict 来创建 series:
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon':16000, 'Utah': 5000}
obj3 = pd.Series(sdata) obj3
Ohio 35000 Oregon 16000 Texas 71000 Utah 5000 dtype: int64
series 中的 index 其实就是 dict 中排好序的 keys。我们也可以传入一个自己想要的顺序:
states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = pd.Series(sdata, index=states) obj4
California NaN Ohio 35000.0 Oregon 16000.0 Texas 71000.0 dtype: float64
顺序是按 states 里来的,但因为没有找到 california,所以是 NaN。NaN 表示缺失数据,用之后我们提到的话就用 missing 或 NA 来指代。pandas 中的 isnull 和 notnull 函数可以用来检测缺失数据:
pd.isnull(obj4)
California True Ohio False Oregon False Texas False dtype: bool
pd.notnull(obj4)
California False Ohio True Oregon True Texas True dtype: bool
series 也有对应的方法:
obj4.isnull()
California True Ohio False Oregon False Texas False dtype: bool
关于缺失数据,在第七章还会讲得更详细一些。
series 中一个有用的特色自动按 index label 来排序(Data alignment features):
obj3
Ohio 35000 Oregon 16000 Texas 71000 Utah 5000 dtype: int64
obj4
California NaN Ohio 35000.0 Oregon 16000.0 Texas 71000.0 dtype: float64
obj3 + obj4
California NaN Ohio 70000.0 Oregon 32000.0 Texas 142000.0 Utah NaN dtype: float64
这个 Data alignment features(数据对齐特色)和数据库中的 join 相似。
serice 自身和它的 index 都有一个叫 name 的属性,这个能和其他 pandas 的函数进行整合:
obj4.name = 'population'
obj4.index.name = 'state'
obj4
state California NaN Ohio 35000.0 Oregon 16000.0 Texas 71000.0 Name: population, dtype: float64
series 的 index 能被直接更改:
obj
0 4 1 7 2 -5 3 3 dtype: int64
obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan'] obj
Bob 4 Steve 7 Jeff -5 Ryan 3 dtype: int64
2 DataFrame
DataFrame 表示一个长方形表格,并包含排好序的列,每一列都可以是不同的数值类型(数字,字符串,布尔值)。DataFrame 有行索引和列索引(row index, column index);可以看做是分享所有索引的由 series 组成的字典。数据是保存在一维以上的区块里的。
(其实我是把 dataframe 当做 excel 里的那种表格来用的,这样感觉更直观一些)
构建一个 dataframe 的方法,用一个 dcit,dict 里的值是 list:
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002, 2003], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]} frame = pd.DataFrame(data) frame
pop | state | year | |
---|---|---|---|
0 | 1.5 | Ohio | 2000 |
1 | 1.7 | Ohio | 2001 |
2 | 3.6 | Ohio | 2002 |
3 | 2.4 | Nevada | 2001 |
4 | 2.9 | Nevada | 2002 |
5 | 3.2 | Nevada | 2003 |
dataframe 也会像 series 一样,自动给数据赋 index, 而列则会按顺序排好。
对于一个较大的 DataFrame,用 head 方法会返回前 5 行(注:这个函数在数据分析中经常使用,用来查看表格里有什么东西):
frame.head()
pop | state | year | |
---|---|---|---|
0 | 1.5 | Ohio | 2000 |
1 | 1.7 | Ohio | 2001 |
2 | 3.6 | Ohio | 2002 |
3 | 2.4 | Nevada | 2001 |
4 | 2.9 | Nevada | 2002 |
如果指定一列的话,会自动按列排序:
pd.DataFrame(data, columns=['year', 'state', 'pop'])
year | state | pop | |
---|---|---|---|
0 | 2000 | Ohio | 1.5 |
1 | 2001 | Ohio | 1.7 |
2 | 2002 | Ohio | 3.6 |
3 | 2001 | Nevada | 2.4 |
4 | 2002 | Nevada | 2.9 |
5 | 2003 | Nevada | 3.2 |
如果你导入一个不存在的列名,那么会显示为缺失数据:
frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five', 'six'])
frame2
year | state | pop | debt | |
---|---|---|---|---|
one | 2000 | Ohio | 1.5 | NaN |
two | 2001 | Ohio | 1.7 | NaN |
three | 2002 | Ohio | 3.6 | NaN |
four | 2001 | Nevada | 2.4 | NaN |
five | 2002 | Nevada | 2.9 | NaN |
six | 2003 | Nevada | 3.2 | NaN |
frame2.columns
Index(['year', 'state', 'pop', 'debt'], dtype='object')
从 DataFrame 里提取一列的话会返回 series 格式,可以以属性或是 dict 一样的形式来提取:
frame2['state']
one Ohio two Ohio three Ohio four Nevada five Nevada six Nevada Name: state, dtype: object
frame2.year
one 2000 two 2001 three 2002 four 2001 five 2002 six 2003 Name: year, dtype: int64
注意:frame2[column]能应对任何列名,但 frame2.column 的情况下,列名必须是有效的 python 变量名才行。
返回的 series 有 DataFrame 种同样的 index,而且 name 属性也是对应的。
对于行,要用在 loc 属性里用 位置或名字:
frame2.loc['three']
year 2002 state Ohio pop 3.6 debt NaN Name: three, dtype: object
列值也能通过赋值改变。比如给 debt 赋值:
frame2['debt'] = 16.5 frame2
year | state | pop | debt | |
---|---|---|---|---|
one | 2000 | Ohio | 1.5 | 16.5 |
two | 2001 | Ohio | 1.7 | 16.5 |
three | 2002 | Ohio | 3.6 | 16.5 |
four | 2001 | Nevada | 2.4 | 16.5 |
five | 2002 | Nevada | 2.9 | 16.5 |
six | 2003 | Nevada | 3.2 | 16.5 |
frame2['debt'] = np.arange(6.) frame2
year | state | pop | debt | |
---|---|---|---|---|
one | 2000 | Ohio | 1.5 | 0.0 |
two | 2001 | Ohio | 1.7 | 1.0 |
three | 2002 | Ohio | 3.6 | 2.0 |
four | 2001 | Nevada | 2.4 | 3.0 |
five | 2002 | Nevada | 2.9 | 4.0 |
six | 2003 | Nevada | 3.2 | 5.0 |
如果把 list 或 array 赋给 column 的话,长度必须符合 DataFrame 的长度。如果把一二 series 赋给 DataFrame,会按 DataFrame 的 index 来赋值,不够的地方用缺失数据来表示:
val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five']) frame2['debt'] = val frame2
year | state | pop | debt | |
---|---|---|---|---|
one | 2000 | Ohio | 1.5 | NaN |
two | 2001 | Ohio | 1.7 | -1.2 |
three | 2002 | Ohio | 3.6 | NaN |
four | 2001 | Nevada | 2.4 | -1.5 |
five | 2002 | Nevada | 2.9 | -1.7 |
six | 2003 | Nevada | 3.2 | NaN |
如果列不存在,赋值会创建一个新列。而 del 也能像删除字典关键字一样,删除列:
frame2['eastern'] = frame2.state == 'Ohio' frame2
year | state | pop | debt | eastern | |
---|---|---|---|---|---|
one | 2000 | Ohio | 1.5 | NaN | True |
two | 2001 | Ohio | 1.7 | -1.2 | True |
three | 2002 | Ohio | 3.6 | NaN | True |
four | 2001 | Nevada | 2.4 | -1.5 | False |
five | 2002 | Nevada | 2.9 | -1.7 | False |
six | 2003 | Nevada | 3.2 | NaN | False |
然后用 del 删除这一列:
del frame2['eastern']
frame2.columns
Index(['year', 'state', 'pop', 'debt'], dtype='object')
注意:columns 返回的是一个 view,而不是新建了一个 copy。因此,任何对 series 的改变,会反映在 DataFrame 上。除非我们用 copy 方法来新建一个。
另一种常见的格式是 dict 中的 dict:
pop = {'Nevada': {2001: 2.4, 2002: 2.9}, 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
把上面这种嵌套 dcit 传给 DataFrame,pandas 会把外层 dcit 的 key 当做列,内层 key 当做行索引:
frame3 = pd.DataFrame(pop) frame3
Nevada | Ohio | |
---|---|---|
2000 | NaN | 1.5 |
2001 | 2.4 | 1.7 |
2002 | 2.9 | 3.6 |
另外 DataFrame 也可以向 numpy 数组一样做转置:
frame3.T
2000 | 2001 | 2002 | |
---|---|---|---|
Nevada | NaN | 2.4 | 2.9 |
Ohio | 1.5 | 1.7 | 3.6 |
指定 index:
pd.DataFrame(pop, index=[2001, 2002, 2003])
Nevada | Ohio | |
---|---|---|
2001 | 2.4 | 1.7 |
2002 | 2.9 | 3.6 |
2003 | NaN | NaN |
series 组成的 dict:
pdata = {'Ohio': frame3['Ohio'][:-1], 'Nevada': frame3['Nevada'][:2]}
pd.DataFrame(pdata)
Nevada | Ohio | |
---|---|---|
2000 | NaN | 1.5 |
2001 | 2.4 | 1.7 |
其他一些可以传递给 DataFrame 的构造器:
如果 DataFrame 的 index 和 column 有自己的 name 属性,也会被显示:
frame3.index.name = 'year'; frame3.columns.name = 'state'
frame3
state | Nevada | Ohio |
---|---|---|
year | ||
2000 | NaN | 1.5 |
2001 | 2.4 | 1.7 |
2002 | 2.9 | 3.6 |
values 属性会返回二维数组:
frame3.values
array([[ nan, 1.5], [ 2.4, 1.7], [ 2.9, 3.6]])
如果 column 有不同的类型,dtype 会适应所有的列:
frame2.values
array([[2000, 'Ohio', 1.5, nan], [2001, 'Ohio', 1.7, -1.2], [2002, 'Ohio', 3.6, nan], [2001, 'Nevada', 2.4, -1.5], [2002, 'Nevada', 2.9, -1.7], [2003, 'Nevada', 3.2, nan]], dtype=object)
3 Index Objects (索引对象)
pandas 的 Index Objects (索引对象)负责保存 axis labels 和其他一些数据(比如 axis name 或 names)。一个数组或其他一个序列标签,只要被用来做构建 series 或 DataFrame,就会被自动转变为 index:
obj = pd.Series(range(3), index=['a', 'b', 'c'])
index = obj.index index
Index(['a', 'b', 'c'], dtype='object')
index[1:]
Index(['b', 'c'], dtype='object')
index object 是不可更改的:
index[1] = 'd'
正因为不可修改,所以 data structure 中分享 index object 是很安全的:
labels = pd.Index(np.arange(3)) labels
Int64Index([0, 1, 2], dtype='int64')
obj2 = pd.Series([1.5, -2.5, 0], index=labels) obj2
0 1.5 1 -2.5 2 0.0 dtype: float64
obj2.index is labels
True
index 除了想数组,还能像大小一定的 set:
frame3
state | Nevada | Ohio |
---|---|---|
year | ||
2000 | NaN | 1.5 |
2001 | 2.4 | 1.7 |
2002 | 2.9 | 3.6 |
frame3.columns
Index(['Nevada', 'Ohio'], dtype='object', name='state')
'Ohio' in frame3.columns
True
2003 in frame3.columns
False
与 python 里的 set 不同,pandas 的 index 可以有重复的 labels:
dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar']) dup_labels
Index(['foo', 'foo', 'bar', 'bar'], dtype='object')
在这种重复的标签中选择的话,会选中所有相同的标签。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论