Head 与 Tail
head()
与 tail()
用于快速预览 Series 与 DataFrame,默认显示 5 条数据,也可以指定显示数据的数量。
属性与底层数据
Pandas 可以通过多个属性访问元数据:
-
shape:
- 输出对象的轴维度,与 ndarray 一致
-
轴标签
- Series: Index (仅有此轴)
- DataFrame: Index (行) 与列
注意: 为属性赋值是安全的!
Pandas 对象(Index
, Series
, DataFrame
)相当于数组的容器,用于存储数据、执行计算。大部分类型的底层数组都是 numpy.ndarray
。不过,Pandas 与第三方支持库一般都会扩展 NumPy 类型系统,添加自定义数组(见数据类型)。
.array
属性用于提取 Index
或 Series
里的数据。
提取 NumPy 数组,用 to_numpy()
或 numpy.asarray()
。
to_numpy()
可以控制 numpy.ndarray
生成的数据类型。以带时区的 datetime 为例,NumPy 未提供时区信息的 datetime 数据类型,Pandas 则提供了两种表现形式:
-
一种是带
Timestamp
的numpy.ndarray
,提供了正确的tz
信息。 -
另一种是
datetime64[ns]
,这也是一种numpy.ndarray
,值被转换为 UTC,但去掉了时区信息。
时区信息可以用 dtype=object
保存。
或用 dtype='datetime64[ns]'
去除。
提取 DataFrame
里的原数据稍微有点复杂。DataFrame 里所有列的数据类型都一样时,DataFrame.to_numpy()
返回底层数据:
匹配/广播机制
DataFrame 支持 add()
、sub()
、mul()
、div()
及 radd()
、rsub()
等方法执行二进制操作。
广播机制重点关注输入的 Series。通过 axis
关键字,匹配 index 或 columns 即可调用这些函数。
还可以用 Series 对齐多层索引 DataFrame 的某一层级。
Series 与 Index 还支持 divmod()
内置函数,该函数同时执行向下取整除与模运算,返回两个与左侧类型相同的元组。示例如下:
divmod()
还支持元素级运算:
缺失值与填充缺失值操作
Series 与 DataFrame 的算数函数支持 fill_value
选项,即用指定值替换某个位置的缺失值。比如,两个 DataFrame 相加,除非两个 DataFrame 里同一个位置都有缺失值,其相加的和仍为 NaN
,如果只有一个 DataFrame 里存在缺失值,则可以用 fill_value
指定一个值来替代 NaN
,当然,也可以用 fillna
把 NaN
替换为想要的值。
比较操作
与上一小节的算数运算类似,Series 与 DataFrame 还支持 eq
、ne
、lt
、gt
、le
、ge
等二进制比较操作的方法:
布尔简化
empty
、any()
、all()
、bool()
可以把数据汇总简化至单个布尔值。
还可以进一步把上面的结果简化为单个布尔值。
通过 empty
属性,可以验证 Pandas 对象是否为空。
比较对象是否等效
一般情况下,多种方式都能得出相同的结果。以 df + df
与 df * 2
为例。
应用上一小节学到的知识,测试这两种计算方式的结果是否一致,一般人都会用 (df + df == df * 2).all()
,不过,这个表达式的结果是 False
:
注意:布尔型 DataFrame df + df == df * 2
中有 False
值!这是因为两个 NaN
值的比较结果为不等:
为了验证数据是否等效,Series 与 DataFrame 等 N 维框架提供了 equals()
方法,用这个方法验证 NaN
值的结果为相等。
注意:Series 与 DataFrame 索引的顺序必须一致,验证结果才能为 True
:
合并重叠数据集
一个 DataFrame 中的缺失值将按指定条件用另一个 DataFrame 里类似标签中的数据进行填充。要实现这一操作,请用下列代码中的 combine_first()
函数。
描述性统计
Series 与 DataFrame 支持大量计算描述性统计的方法与操作。这些方法大部分都是 sum()
、mean()
、quantile()
等聚合函数,其输出结果比原始数据集小;此外,还有输出结果与原始数据集同样大小的 cumsum()
、 cumprod()
等函数。这些方法都基本上都接受 axis
参数,如, ndarray.{sum,std,…}
,但这里的 axis
可以用名称或整数指定:
- Series:无需
axis
参数 - DataFrame:
index
,即axis=0
,默认值columns
, 即axis=1
上述方法都支持 skipna
关键字,指定是否要排除缺失数据,默认值为 True
。
注 : cumsum()
与 cumprod()
等方法保留 NaN
值的位置。这与 expanding()
和 rolling()
略显不同,详情请参阅本文。
下表为常用函数汇总表。每个函数都支持 level
参数,仅在数据对象为结构化 Index 时使用。
函数 | 描述 |
---|---|
count |
统计非空值数量 |
sum |
汇总值 |
mean |
平均值 |
mad |
平均绝对偏差 |
median |
算数中位数 |
min |
最小值 |
max |
最大值 |
mode |
众数 |
abs |
绝对值 |
prod |
乘积 |
std |
贝塞尔校正的样本标准偏差 |
var |
无偏方差 |
sem |
平均值的标准误差 |
skew |
样本偏度 (第三阶) |
kurt |
样本峰度 (第四阶) |
quantile |
样本分位数 (不同 % 的值) |
cumsum |
累加 |
cumprod |
累乘 |
cummax |
累积最大值 |
cummin |
累积最小值 |
注意:NumPy 的 mean
、std
、sum
等方法默认不统计 Series 里的空值。但是narray 空值会计算
Series.nunique()
返回 Series 里所有非空值的唯一值。
数据总结:describe
最大值与最小值对应的索引
值计数(直方图)与众数
与上述操作类似,还可以统计 Series 或 DataFrame 的众数,即出现频率最高的值:
离散化与分位数
cut() 函数
(以值为依据实现分箱)及 qcut() 函数
(以样本分位数为依据实现分箱)用于连续值的离散化:
函数应用
不管是为 Pandas 对象应用自定义函数,还是应用第三方函数,都离不开以下三种方法。用哪种方法取决于操作的对象是 DataFrame
,还是 Series
;是行、列,还是元素。
-
表级函数应用:
pipe()
-
行列级函数应用:
apply()
-
聚合 API:
agg()
与transform()
-
元素级函数应用:
applymap()
#表级函数应用
虽然可以把 DataFrame 与 Series 传递给函数,不过链式调用函数时,最好使用 pipe()
方法。对比以下两种方式:
pipe()
方法。对比以下两种方式:
f(g(h(df), arg1=1), arg2=2, arg3=3)
(df.pipe(h).pipe(g, arg1=1).pipe(f, arg2=2, arg3=3))
后面再补充吧,没看懂
行列级函数应用
apply()
方法沿着 DataFrame 的轴应用函数,比如,描述性统计方法,该方法支持 axis
参数。
用好 apply()
可以了解数据集的很多信息。比如可以提取每列的最大值对应的日期:
聚合 API
聚合 API 可以快速、简洁地执行多个聚合操作。Pandas 对象支持多个类似的 API,如 groupby API、window functions API、resample API。
聚合函数为DataFrame.aggregate()
,它的别名是 DataFrame.agg()
。
应用单个函数时,该操作与 apply()
等效,这里也可以用字符串表示聚合函数名。下面的聚合函数输出的结果为 Series
:
Series
单个聚合操作返回标量值:
多函数聚合
还可以用列表形式传递多个聚合函数。每个函数在输出结果 DataFrame
里以行的形式显示,行名是每个聚合函数的函数名。.
Series
聚合多函数返回结果还是 Series
,索引为函数名:
传递 lambda
函数时,输出名为 <lambda>
的行:
指定为哪些列应用哪些聚合函数时,需要把包含列名与标量(或标量列表)的字典传递给 DataFrame.agg
。
注意:这里输出结果的顺序不是固定的,要想让输出顺序与输入顺序一致,请使用 OrderedDict
。
Transform API
0.20.0 版新增。
transform()
方法的返回结果与原始数据的索引相同,大小相同。与 .agg
API 类似,该 API 支持同时处理多种操作,不用一个一个操作。
多函数 Transform
transform()
调用多个函数时,生成多层索引 DataFrame。第一层是原始数据集的列名;第二层是 transform()
调用的函数名。
用字典执行 transform
操作
函数字典可以为每列执行指定 transform()
操作。
元素级函数应用
并非所有函数都能矢量化,即接受 NumPy 数组,返回另一个数组或值,DataFrame 的 applymap()
及 Series 的 map()
,支持任何接收单个值并返回单个值的 Python 函数。
Series.map()
还有个功能,可以“连接”或“映射”第二个 Series 定义的值。这与 merging / joining 功能联系非常紧密:
重置索引与更换标签
reindex()
是 Pandas 里实现数据对齐的基本方法,该方法执行几乎所有功能都要用到的标签对齐功能。 reindex
指的是沿着指定轴,让数据与给定的一组标签进行匹配。该功能完成以下几项操作:
- 让现有数据匹配一组新标签,并重新排序;
- 在无数据但有标签的位置插入缺失值(
NA
)标记; - 如果指定,则按逻辑填充无标签的数据,该操作多见于时间序列数据。
DataFrame 支持同时 reindex
索引与列:
reindex
还支持 axis
关键字:
重置索引,并与其它对象对齐
提取一个对象,并用另一个具有相同标签的对象 reindex
该对象的轴。这种操作的语法虽然简单,但未免有些啰嗦。
这时,最好用 reindex_like()
方法,这是一种既有效,又简单的方式:
用 align
对齐多个对象
align()
方法是对齐两个对象最快的方式,该方法支持 join
参数
join='outer'
:使用两个对象索引的合集,默认值join='left'
:使用左侧调用对象的索引join='right'
:使用右侧传递对象的索引join='inner'
:使用两个对象索引的交集
该方法返回重置索引后的两个 Series 元组:
方法 | 动作 |
---|---|
pad / ffill | 先前填充 |
bfill / backfill | 向后填充 |
nearest | 从最近的索引值填充 |
下面用一个简单的 Series 展示 fill
方法:
重置索引填充的限制
limit
与 tolerance
参数可以控制 reindex
的填充操作。limit
限定了连续匹配的最大数量:
反之,tolerance
限定了索引与索引器值之间的最大距离:
去掉轴上的标签
drop()
函数与 reindex
经常配合使用,该函数用于删除轴上的一组标签:
重命名或映射标签
rename()
方法支持按不同的轴基于映射(字典或 Series)调整标签。
如果调用的是函数,该函数在处理标签时,必须返回一个值,而且生成的必须是一组唯一值。此外,rename()
还可以调用字典或 Series。
rename()
方法还提供了 inplace
命名参数,默认为 False
,并会复制底层数据。inplace=True
时,会直接在原数据上重命名。
迭代
Pandas 对象基于类型进行迭代操作。Series 迭代时被视为数组,基础迭代生成值。DataFrame 则遵循字典式习语,用对象的 key
实现迭代操作。
简言之,基础迭代(for i in object
)生成:
- Series :值
- DataFrame:列标签
例如,DataFrame 迭代时输出列名:
项目(items)
与字典型接口类似,items()
通过键值对进行迭代:
- Series:(Index,标量值)对
- DataFrame:(列,Series)对
iterrows
iterrows()
迭代 DataFrame 或 Series 里的每一行数据。这个操作返回一个迭代器,生成索引值及包含每行数据的 Series:
.dt 访问器
Series
提供一个可以简单、快捷地返回 datetime
属性值的访问器。这个访问器返回的也是 Series,索引与现有的 Series 一样。
用下列表达式进行筛选非常方便:
时区转换也很轻松:
还可以用 Series.dt.strftime()
把 datetime
的值当成字符串进行格式化,支持与标准 strftime()
同样的格式。
#矢量化字符串方法
Series 支持字符串处理方法,可以非常方便地操作数组里的每个元素。
这些方法会自动排除缺失值与空值,这也许是其最重要的特性。
这些方法通过 Series 的 str
属性访问,一般情况下,这些操作的名称与内置的字符串方法一致。示例如下:
排序
Pandas 支持三种排序方式,按索引标签排序,按列里的值排序,按两种方式混合排序。
#按索引排序
Series.sort_index()
与 DataFrame.sort_index()
方法用于按索引层级对 Pandas 对象排序。
按值排序
Series.sort_values()
方法用于按值对 Series 排序。
DataFrame.sort_values()
方法用于按行列的值对 DataFrame 排序。
DataFrame.sort_values()
的可选参数 by
用于指定按哪列排序,该参数的值可以是一列或多列数据。
按索引与值排序
通过参数 by
传递给 DataFrame.sort_values()
的字符串可以引用列或索引层名。
搜索排序
Series 支持 searchsorted()
方法,这与numpy.ndarray.searchsorted()
的操作方式类似。
最大值与最小值
Series 支持 nsmallest()
与 nlargest()
方法,本方法返回 N 个最大或最小的值。
对于数据量大的 Series
来说,该方法比先为整个 Series 排序,再调用 head(n)
这种方式的速度要快得多。
DataFrame
也支持 nlargest
与 nsmallest
方法。
#复制
在 Pandas 对象上执行 copy()
方法,将复制底层数据(但不包括轴索引,因为轴索引不可变),并返回一个新的对象。注意,复制对象这种操作一般来说不是必须的。比如说,以下几种方式可以***就地(inplace)*** 改变 DataFrame:
- 插入、删除、修改列
- 为
index
或columns
属性赋值 - 对于同质数据,用
values
属性或高级索引即可直接修改值
注意,用 Pandas 方法修改数据不会带来任何副作用,几乎所有方法都返回新的对象,不会修改原始数据对象。
如果原始数据有所改动,唯一的可能就是用户显式指定了要修改原始数据