Pandas基本使用方法
Pandas有三个基本的数据结构:Series、DataFrame和Index
Pandas的Series对象是一个带索引数据构成的一维数组
可以用数组创建Series对象:
import pandas as pd
import numpy as np
data = pd.Series([0.25, 0.5, 0.75, 1.0])
data
0 0.25
1 0.50
2 0.75
3 1.00
dtype: float64
从上面的结果中可以看出,Series对象将一维数组数据和一组索引绑定在一起,可以通过values属性和index属性获取数据,values属性返回的结果与Numpy数组类似:
print(data.values)
type(data.values)
[0.25 0.5 0.75 1. ]
numpy.ndarray
index属性返回的是一个类型为pd.Index的类数组对象
print(data.index)
print(type(data.index))
RangeIndex(start=0, stop=4, step=1)
<class 'pandas.core.indexes.range.RangeIndex'>
和Numpy数组一样,数据可以通过Python中括号索引标签获取
print(data[1])
print(data[1:3])
0.5
1 0.50
2 0.75
dtype: float64
Pandas的Series与Numpy的一维数组的本质差别是Series对象用一种显示定义的索引与数值关联,显示索引定义可以是任意想要的类型
data = pd.Series([0.25, 0.5, 0.75, 1.0], index=['a','b','c','d'])
data
a 0.25
b 0.50
c 0.75
d 1.00
dtype: float64
获取数值的方式与之前一样:
data['b']
0.5
也可以使用不连续或者不按顺序的索引:
data = pd.Series([0.25, 0.5, 0.75, 1.0], index=[2,5,3,7])
data
2 0.25
5 0.50
3 0.75
7 1.00
dtype: float64
data[5]
0.5
Series也是一种特殊类型的字典,操作起来比python的字典更加高效。
可以直接使用Python的字典创建一个Series对象,让Series对象比字典更加清晰:
population_dict = {'California':38332521,
'Texas':26448193,
'New York':19651127,
'Florida':19552860,
'Illinois':12882135}
population = pd.Series(population_dict)
population
California 38332521
Texas 26448193
New York 19651127
Florida 19552860
Illinois 12882135
dtype: int64
population['California']
38332521
和字典不用,Series对象还支持数组类型的操作,比如切片:左右都闭
population['California':'Florida']
California 38332521
Texas 26448193
New York 19651127
Florida 19552860
dtype: int64
创建Series对象的集中方式:index是可选参数,data可以是列表或者numpy数组,或者是字典,也可以是标量,创建Series对象时会重复填充到每个索引上。
pd.Series(5,index=[100,200,300])
100 5
200 5
300 5
dtype: int64
data还可以是一个字典,可以通过显示指定索引筛选需要的结果
pd.Series({2:'a', 1:'b', 3:'c'},index=[2,3])
2 a
3 c
dtype: object
Pandas的DataFrame对象是一个二维的带有索引的数组。
可以用字典来创建DateFrame对象:
area_dict = {'California': 423967, 'Texas': 695662, 'New York': 141297,
'Florida': 170312, 'Illinois': 149995}
area = pd.Series(area_dict)
area
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
dtype: int64
states = pd.DataFrame({'population':population,'area':area})
states
population | area | |
---|---|---|
California | 38332521 | 423967 |
Texas | 26448193 | 695662 |
New York | 19651127 | 141297 |
Florida | 19552860 | 170312 |
Illinois | 12882135 | 149995 |
和Series一样,DataFrame也有一个index属性可以获取索引标签。
states.index
Index(['California', 'Texas', 'New York', 'Florida', 'Illinois'], dtype='object')
另外,DataFrame还有一个columns属性,存放的是列标签的index
states.columns
Index(['population', 'area'], dtype='object')
DataFrame也是一个特殊的字典,DataFrame是一列映射一个Series数据,这里需要注意的是,在 NumPy 的二维数组里, data[0]返回第一行;而在 DataFrame 中,data[‘col0’]返回第一列。
states['area']
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
创建DataFrame对象:
(1)通过单个Series对象创建
pd.DataFrame(population,columns=['population'])
population | |
---|---|
California | 38332521 |
Texas | 26448193 |
New York | 19651127 |
Florida | 19552860 |
Illinois | 12882135 |
(2)通过字典列表创建,任何元素是字典的列表都可以变成 DataFrame 。用一个简单的列表
综合来创建一些数据:
data = [{'a':i, 'b':2*i} for i in range(3)]
data
[{'a': 0, 'b': 0}, {'a': 1, 'b': 2}, {'a': 2, 'b': 4}]
pd.DataFrame(data)
a | b | |
---|---|---|
0 | 0 | 0 |
1 | 1 | 2 |
2 | 2 | 4 |
(3)通过Series对象创建DataFrame
pd.DataFrame({'population':population, 'area':area})
population | area | |
---|---|---|
California | 38332521 | 423967 |
Texas | 26448193 | 695662 |
New York | 19651127 | 141297 |
Florida | 19552860 | 170312 |
Illinois | 12882135 | 149995 |
(4)通过numpy二维数组创建。假如有一个二维数组,就可以创建一个可以指定行列索引值的 DataFrame 。如果不指定行列索引值,那么行列默认都是整数索引值:
pd.DataFrame(np.random.rand(3,2))
0 | 1 | |
---|---|---|
0 | 0.598602 | 0.090202 |
1 | 0.024323 | 0.922540 |
2 | 0.412261 | 0.443546 |
pd.DataFrame(np.random.rand(3,2), index=['a','b','c'],columns=['foo','bar'])
foo | bar | |
---|---|---|
a | 0.843181 | 0.250314 |
b | 0.768702 | 0.204884 |
c | 0.360192 | 0.082351 |
(5)通过numpy的结构化数组创建
A = np.zeros(3,dtype=[('A','i8'),('B','f8')])
A
array([(0, 0.), (0, 0.), (0, 0.)], dtype=[('A', '<i8'), ('B', '<f8')])
pd.DataFrame(A)
A | B | |
---|---|---|
0 | 0 | 0.0 |
1 | 0 | 0.0 |
2 | 0 | 0.0 |
Pandas的Index对象
可以将Index对象看做一个不可变数组:不能改变数值
ind = pd.Index([2,3,5,8,9])
ind
Int64Index([2, 3, 5, 8, 9], dtype='int64')
ind[1]
3
ind[::3]
Int64Index([2, 8], dtype='int64')
Index对象还有很多与numpy数组类似的属性
print(ind.shape, ind.size, ind.ndim, ind.dtype)
(5,) 5 1 int64
将Index看做有序集合
indA = pd.Index([1,3,5,7,9])
indB = pd.Index([2,3,5,7,8])
indA & indB
Int64Index([3, 5, 7], dtype='int64')
indA | indB
Int64Index([1, 2, 3, 5, 7, 8, 9], dtype='int64')
indA ^ indB
Int64Index([1, 2, 8, 9], dtype='int64')
Pandas的数据选取与选择
(1)Series的数据选择方法:可以将Series对象看做一个字典
data = pd.Series([0.25, 0.5, 0.75, 1.0], index=list('abcd'))
data
a 0.25
b 0.50
c 0.75
d 1.00
dtype: float64
data['b']
0.5
还可以通过Python字典的表达式和方法来检测key和value
'a' in data
True
data.keys()
Index(['a', 'b', 'c', 'd'], dtype='object')
list(data.items())
[('a', 0.25), ('b', 0.5), ('c', 0.75), ('d', 1.0)]
Series对象还可以用字典语法调整数据,可以 通过增加新的索引扩展Series
data['e'] = 1.5
data
a 0.25
b 0.50
c 0.75
d 1.00
e 1.50
dtype: float64
(2)可以将Series看做一个数组:索引、掩码、花哨索引等操作
# 切片
data['a':'c']
a 0.25
b 0.50
c 0.75
dtype: float64
# 将隐式整数作为切片
data[0:2]
a 0.25
b 0.50
dtype: float64
# 掩码
data[(data>0.3)&(data<0.8)]
b 0.50
c 0.75
dtype: float64
# 花哨的索引
data[['a','c']]
a 0.25
c 0.75
dtype: float64
需 要 注 意 的 是, 当 使 用 显 式 索 引( 即data[‘a’:‘c’])作切片时,结果包含最后一个索引;而当使用隐式索引(即 data[0:2] )作切片时,结果不包含最后一个索引。
(3)索引器:loc、iloc和ix
这些切片和取值的习惯用法经常会造成混乱。例如,如果你的 Series 是显式整数索引,那么
data[1] 这样的取值操作会使用显式索引,而 data[1:3] 这样的切片操作却会使用隐式索引。
data = pd.Series(['a','b','c'],index=[1,3,5])
data
1 a
3 b
5 c
dtype: object
data[1:3]
3 b
5 c
dtype: object
由于整数索引很容易造成混淆,所以Pandas提供了一些索引器属性来作为取值的方法。他们不是Series对象的函数方法,而是暴露切片接口的属性,
第一种是loc属性,表示取值和切片都是显示的
data.loc[1]
'a'
data.loc[1:3]
1 a
3 b
dtype: object
第二种是iloc属性,表示取值和切片都是隐示索引
data.iloc[0]
'a'
data.iloc[1:3]
3 b
5 c
dtype: object
第三种是ix属性,是前两种的混合形式,用于DataFrame
DataFrame的数据选择方法
(1)将DataFrame看做字典
area = pd.Series({'California': 423967, 'Texas': 695662,
'New York': 141297, 'Florida': 170312,
'Illinois': 149995})
pop = pd.Series({'California': 38332521, 'Texas': 26448193,
'New York': 19651127, 'Florida': 19552860,
'Illinois': 12882135})
data = pd.DataFrame({'area':area, 'pop':pop})
data
area | pop | |
---|---|---|
California | 423967 | 38332521 |
Texas | 695662 | 26448193 |
New York | 141297 | 19651127 |
Florida | 170312 | 19552860 |
Illinois | 149995 | 12882135 |
两个 Series 分别构成 DataFrame 的一列,可以通过对列名进行字典形式(dictionary-style)的取值获取数据:
data['area']
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
也可以通过属性的方式:
data.area
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
和前面介绍的 Series 对象一样,还可以用字典形式的语法调整对象,如果要增加一列可以
这样做:
data['denstiy'] = data['pop']/data['area']
data
area | pop | denstiy | |
---|---|---|---|
California | 423967 | 38332521 | 90.413926 |
Texas | 695662 | 26448193 | 38.018740 |
New York | 141297 | 19651127 | 139.076746 |
Florida | 170312 | 19552860 | 114.806121 |
Illinois | 149995 | 12882135 | 85.883763 |
(2)将DataFrame看做二维数组
使用values直接查看数据
data.values
array([[4.23967000e+05, 3.83325210e+07, 9.04139261e+01],
[6.95662000e+05, 2.64481930e+07, 3.80187404e+01],
[1.41297000e+05, 1.96511270e+07, 1.39076746e+02],
[1.70312000e+05, 1.95528600e+07, 1.14806121e+02],
[1.49995000e+05, 1.28821350e+07, 8.58837628e+01]])
data.T
California | Texas | New York | Florida | Illinois | |
---|---|---|---|---|---|
area | 4.239670e+05 | 6.956620e+05 | 1.412970e+05 | 1.703120e+05 | 1.499950e+05 |
pop | 3.833252e+07 | 2.644819e+07 | 1.965113e+07 | 1.955286e+07 | 1.288214e+07 |
denstiy | 9.041393e+01 | 3.801874e+01 | 1.390767e+02 | 1.148061e+02 | 8.588376e+01 |
data.values[0]
array([4.23967000e+05, 3.83325210e+07, 9.04139261e+01])
data['area']
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
data.iloc[:3,:2]
area | pop | |
---|---|---|
California | 423967 | 38332521 |
Texas | 695662 | 26448193 |
New York | 141297 | 19651127 |
使用 ix 索引器可以实现一种混合效果:容易混淆
# data.ix[:3,:'pop']
掩码操作
data.loc[data.denstiy>100]
area | pop | denstiy | |
---|---|---|---|
New York | 141297 | 19651127 | 139.076746 |
Florida | 170312 | 19552860 | 114.806121 |
data.loc[data.denstiy>100,['pop','density']]
/home/ldy/.pyenv/versions/3.6.8/lib/python3.6/site-packages/pandas/core/indexing.py:1418: FutureWarning:
Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.
See the documentation here:
https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#deprecate-loc-reindex-listlike
return self._getitem_tuple(key)
pop | density | |
---|---|---|
New York | 19651127 | NaN |
Florida | 19552860 | NaN |
Pandas数值运算方法
(1)通用函数 : 保留索引
rng = np.random.RandomState(42)
ser = pd.Series(rng.randint(0, 10, 4))
ser
0 6
1 3
2 7
3 4
dtype: int64
df = pd.DataFrame(rng.randint(0, 10, (3, 4)),
columns=['A', 'B', 'C', 'D'])
df
A | B | C | D | |
---|---|---|---|---|
0 | 6 | 9 | 2 | 6 |
1 | 7 | 4 | 3 | 7 |
2 | 7 | 2 | 5 | 4 |
np.exp(ser)
0 403.428793
1 20.085537
2 1096.633158
3 54.598150
dtype: float64
np.sin(df * np.pi / 4)
A | B | C | D | |
---|---|---|---|---|
0 | -1.000000 | 7.071068e-01 | 1.000000 | -1.000000e+00 |
1 | -0.707107 | 1.224647e-16 | 0.707107 | -7.071068e-01 |
2 | -0.707107 | 1.000000e+00 | -0.707107 | 1.224647e-16 |
(2)通用函数 : 索引对齐
当在两个 Series 或 DataFrame 对象上进行二元计算时,Pandas 会在计算过程中对齐两个对象的索引。
area = pd.Series({'Alaska': 1723337, 'Texas': 695662,
'California': 423967}, name='area')
population = pd.Series({'California': 38332521, 'Texas': 26448193,
'New York': 19651127}, name='population')
population / area
Alaska NaN
California 90.413926
New York NaN
Texas 38.018740
dtype: float64
结果数组的索引是两个输入数组索引的并集。我们也可以用 Python 标准库的集合运算法则
来获得这个索引:
area.index | population.index
Index(['Alaska', 'California', 'New York', 'Texas'], dtype='object')
对于缺失位置的数据,Pandas 会用 NaN 填充,表示“此处无数”。这是 Pandas 表示缺失值
的方法.
A = pd.Series([2, 4, 6], index=[0, 1, 2])
B = pd.Series([1, 3, 5], index=[1, 2, 3])
A + B
0 NaN
1 5.0
2 9.0
3 NaN
dtype: float64
如果用 NaN 值不是我们想要的结果,那么可以用适当的对象方法代替运算符。例如,
A.add(B) 等价于 A + B ,也可以设置参数自定义 A 或 B 缺失的数据:
A.add(B, fill_value=0)
0 2.0
1 5.0
2 9.0
3 5.0
dtype: float64
DataFrame索引对齐
A = pd.DataFrame(rng.randint(0, 20, (2, 2)),columns=list('AB'))
A
A | B | |
---|---|---|
0 | 1 | 11 |
1 | 5 | 1 |
B = pd.DataFrame(rng.randint(0, 10, (3, 3)),columns=list('BAC'))
B
B | A | C | |
---|---|---|---|
0 | 4 | 0 | 9 |
1 | 5 | 8 | 0 |
2 | 9 | 2 | 6 |
A+B
A | B | C | |
---|---|---|---|
0 | 1.0 | 15.0 | NaN |
1 | 13.0 | 6.0 | NaN |
2 | NaN | NaN | NaN |
你会发现,两个对象的行列索引可以是不同顺序的,结果的索引会自动按顺序排列。在
Series 中,我们可以通过运算符方法的 fill_value 参数自定义缺失值。这里,我们将用 A
中所有值的均值来填充缺失值(计算 A 的均值需要用 stack 将二维数组压缩成一维数组):
fill = A.stack().mean()
A.add(B, fill_value=fill)
A | B | C | |
---|---|---|---|
0 | 1.0 | 15.0 | 13.5 |
1 | 13.0 | 6.0 | 4.5 |
2 | 6.5 | 13.5 | 10.5 |
(3)通用函数 : DataFrame 与 Series 的运算
A = rng.randint(10, size=(3, 4))
A
array([[3, 8, 2, 4],
[2, 6, 4, 8],
[6, 1, 3, 8]])
A - A[0]
array([[ 0, 0, 0, 0],
[-1, -2, 2, 4],
[ 3, -7, 1, 4]])
根据 NumPy 的广播规则,让二维数组减自身的一行数据会按行计算。在 Pandas 里默认也是按行运算的:
df = pd.DataFrame(A, columns=list('QRST'))
df - df.iloc[0]
Q | R | S | T | |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
1 | -1 | -2 | 2 | 4 |
2 | 3 | -7 | 1 | 4 |
df.subtract(df['R'], axis=0)
Q | R | S | T | |
---|---|---|---|---|
0 | -5 | 0 | -6 | -4 |
1 | -4 | 0 | -2 | 2 |
2 | 5 | 0 | 2 | 7 |
halfrow = df.iloc[0, ::2]
halfrow
Q 3
S 2
Name: 0, dtype: int64
df - halfrow
Q | R | S | T | |
---|---|---|---|---|
0 | 0.0 | NaN | 0.0 | NaN |
1 | -1.0 | NaN | 2.0 | NaN |
2 | 3.0 | NaN | 1.0 | NaN |
这些行列索引的保留与对齐方法说明 Pandas 在运算时会一直保存这些数据内容,从而避免
在处理数据类型有差异和 / 或维度不一致的 NumPy 数组时可能遇到的问题。
Pandas处理缺省值
(1) None :Python 对象类型的缺失值
vals1 = np.array([1,None,3,4])
vals1
array([1, None, 3, 4], dtype=object)
这里 dtype=object 表示 NumPy 认为由于这个数组是 Python 对象构成的,因此将其类型
判断为 object 。虽然这种类型在某些情景中非常有用,对数据的任何操作最终都会在
Python 层面完成,但是在进行常见的快速操作时,这种类型比其他原生类型数组要消耗
更多的资源:
for dtype in ['object', 'int']:
print("dtype =", dtype)
%timeit np.arange(1E6, dtype=dtype).sum()
print()
dtype = object
44.2 ms ± 553 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
dtype = int
1.27 ms ± 81.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
使用 Python 对象构成的数组就意味着如果你对一个包含 None 的数组进行累计操作,如
sum() 或者 min() ,那么通常会出现类型错误:
# vals1.sum()
(2) NaN : 数值类型的缺失值,另一种缺失值的标签是 NaN (全称 Not a Number,不是一个数字),是一种按照 IEEE 浮点
数标准设计、在任何系统中都兼容的特殊浮点数:
vals2 = np.array([1,np.nan,3,4])
vals2.dtype
dtype('float64')
无论和 NaN 进行何种操作,最终结果都是 NaN :
1 + np.nan
nan
3 * np.nan
nan
虽然这些累计操作的结果定义是合理的(即不会抛出异常),但是并非总是有效的:
vals2.sum(),vals2.min(), vals2.max()
(nan, nan, nan)
NumPy 也提供了一些特殊的累计函数,它们可以忽略缺失值的影响:
np.nansum(vals2),np.nanmin(vals2),np.nanmax(vals2)
(8.0, 1.0, 4.0)
谨记, NaN 是一种特殊的浮点数,不是整数、字符串以及其他数据类型。
(3)Pandas中NaN与None的差异
虽然 NaN 与 None 各有各的用处,但是 Pandas 把它们看成是可以等价交换的,在适当的时
候会将两者进行替换:
pd.Series([1,np.nan,2,None])
0 1.0
1 NaN
2 2.0
3 NaN
dtype: float64
Pandas 会将没有标签值的数据类型自动转换为 NaN 。例如,当我们将整型数组中的一个值设
置为 np.nan 时,这个值就会强制转换成浮点数缺失值 NaN 。
x = pd.Series(range(2))
x
0 0
1 1
dtype: int64
x[0]=None
x
0 NaN
1 1.0
dtype: float64
请注意,除了将整型数组的缺失值强制转换为浮点数,Pandas 还会自动将 None 转换为
NaN 。
处理缺省值
我们已经知道,Pandas 基本上把 None 和 NaN 看成是可以等价交换的缺失值形式。为了完成
这种交换过程,Pandas 提供了一些方法来发现、剔除、替换数据结构中的缺失值,主要包
括以下几种:
isnull():创建一个布尔类型的掩码标签缺失值。
notnull():与 isnull() 操作相反。
dropna():返回一个剔除缺失值的数据。
fillna():返回一个填充了缺失值的数据副本。
(1)发现缺省值:
data = pd.Series([1,np.nan,'hello',None])
data
0 1
1 NaN
2 hello
3 None
dtype: object
data.isnull()
0 False
1 True
2 False
3 True
dtype: bool
布尔类型掩码数组可以直接作为 Series 或 DataFrame 的索引使用:
data[data.notnull()]
0 1
2 hello
dtype: object
在 Series 里使用的 isnull() 和 notnull() 同样适用于 DataFrame ,产生的结果同样是布尔
类型。
(2)剔除缺省值
除了前面介绍的掩码方法,还有两种很好用的缺失值处理方法,分别是 dropna() (剔除缺
失值)和 fillna() (填充缺失值)。在 Series 上使用这些方法非常简单:
data.dropna()
0 1
2 hello
dtype: object
而在 DataFrame 上使用它们时需要设置一些参数,例如下面的 DataFrame :
df = pd.DataFrame([[1,np.nan, 2],
[2, 3, 5],
[np.nan, 4,6]])
df
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | NaN | 2 |
1 | 2.0 | 3.0 | 5 |
2 | NaN | 4.0 | 6 |
我们没法从 DataFrame 中单独剔除一个值,要么是剔除缺失值所在的整行,要么是整列。
根据实际需求,有时你需要剔除整行,有时可能是整列, DataFrame 中的 dropna() 会有一
些参数可以配置。
默认情况下, dropna() 会剔除任何包含缺失值的整行数据:
df.dropna()
0 | 1 | 2 | |
---|---|---|---|
1 | 2.0 | 3.0 | 5 |
可以设置按不同的坐标轴剔除缺失值,比如 axis=1 (或 axis=‘columns’ )会剔除任何包含
缺失值的整列数据:
df.dropna(axis='columns')
2 | |
---|---|
0 | 2 |
1 | 5 |
2 | 6 |
默认设置是 how=‘any’ ,也就是说只要有缺失值就剔除整行或整列(通过 axis 设置坐标
轴)。你还可以设置 how=‘all’ ,这样就只会剔除全部是缺失值的行或列了:
df[3] = np.nan
df
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | NaN | 2 | NaN |
1 | 2.0 | 3.0 | 5 | NaN |
2 | NaN | 4.0 | 6 | NaN |
df.dropna(axis='columns',how='all')
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | NaN | 2 |
1 | 2.0 | 3.0 | 5 |
2 | NaN | 4.0 | 6 |
还可以通过 thresh 参数设置行或列中非缺失值的最小数量,从而实现更加个性化的配置:
df.dropna(axis='rows',thresh=3)
0 | 1 | 2 | 3 | |
---|---|---|---|---|
1 | 2.0 | 3.0 | 5 | NaN |
第 1 行与第 3 行被剔除了,因为它们只包含两个非缺失值。
(3)填充缺省值
有时候你可能并不想移除缺失值,而是想把它们替换成有效的数值。有效的值可能是像
0、1、2 那样单独的值,也可能是经过填充(imputation)或转换(interpolation)得到的。
虽然你可以通过 isnull() 方法建立掩码来填充缺失值,但是 Pandas 为此专门提供了一个
fillna() 方法,它将返回填充了缺失值后的数组副本。
data = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))
data
a 1.0
b NaN
c 2.0
d NaN
e 3.0
dtype: float64
我们将用一个单独的值来填充缺失值,例如用 0:
data.fillna(0)
a 1.0
b 0.0
c 2.0
d 0.0
e 3.0
dtype: float64
可以用缺失值前面的有效值来从前往后填充(forward-fill):
data.fillna(method='ffill')
a 1.0
b 1.0
c 2.0
d 2.0
e 3.0
dtype: float64
也可以用缺失值后面的有效值来从后往前填充(back-fill):
data.fillna(method='bfill')
a 1.0
b 2.0
c 2.0
d 3.0
e 3.0
dtype: float64
DataFrame 的操作方法与 Series 类似,只是在填充时需要设置坐标轴参数 axis :
df
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | NaN | 2 | NaN |
1 | 2.0 | 3.0 | 5 | NaN |
2 | NaN | 4.0 | 6 | NaN |
df.fillna(method='ffill',axis='columns')
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 1.0 | 2.0 | 2.0 |
1 | 2.0 | 3.0 | 5.0 | 5.0 |
2 | NaN | 4.0 | 6.0 | 6.0 |
需要注意的是,假如在从前往后填充时,需要填充的缺失值前面没有值,那么它就仍然是
缺失值。