《利用Python进行数据分析》Chapter 7

在数据分析和建模的过程中,大量的时间花在数据准备上:加载、清理、转换和重新排列。这样的工作占了分析师80%以上的时间。
本章内容主要讲解pandas中用于缺失值、重复值、字符串操作和其他分析数据转换的工具。

1. 处理缺失值

pandas对象的所有描述性统计信息默认情况下是排除缺失值的。对于数值型数据,pandas使用浮点值NaN来表示缺失值,所以NaN是容易检测到的标识值。

1.1 过滤缺失值

a. 在Series上使用dropna,可以返回Series中素有的非空数据及其索引值:

data = pd.Series([1, np.nan, 3.5, np.nan, 7])
data
0    1.0
1    NaN
2    3.5
3    NaN
4    7.0
dtype: float64
cleaned = data.dropna() # 原数组不发生改变, 与data.notnull()等价
cleaned
0    1.0
2    3.5
4    7.0
dtype: float64

b. 对与DataFrame来说有一些选项可以操作:

from numpy import nan as NA # 使用NA来代替np.nan
data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA], [NA, 6.5, 3.]])
data
	0	1	2
0	1.0	6.5	3.0
1	1.0	NaN	NaN
2	NaN	NaN	NaN
3	NaN	6.5	3.0
data.dropna() # 参数默认的情况下删除包含缺失值的所有行
	0	1	2
0	1.0	6.5	3.0
data.dropna(how='all') # 仅删除所有值都是NA的行
	0	1	2
0	1.0	6.5	3.0
1	1.0	NaN	NaN
3	NaN	6.5	3.0
data[4] = NA
data
	0	1	2	4
0	1.0	6.5	3.0	NaN
1	1.0	NaN	NaN	NaN
2	NaN	NaN	NaN	NaN
3	NaN	6.5	3.0	NaN
data.dropna(axis=1, how='all') # 指定轴1来删除列
	0	1	2
0	1.0	6.5	3.0
1	1.0	NaN	NaN
2	NaN	NaN	NaN
3	NaN	6.5	3.0
df = pd.DataFrame(np.random.randn(7, 3))
df.iloc[:4, 1] = NA
df.iloc[:2, 2] = NA
df
		0			1			2
0	-0.049375	NaN			NaN
1	-0.557540	NaN			NaN
2	-0.079590	NaN			1.016858
3	0.035582	NaN			0.562665
4	1.023047	0.485505	-0.086212
5	0.315884	-1.314378	0.916748
6	0.479718	-0.704622	-1.252934
df.dropna(thresh=2) # 保留至少有2个非空值数据的行
		0			1			2
2	-0.079590	NaN			1.016858
3	0.035582	NaN			0.562665
4	1.023047	0.485505	-0.086212
5	0.315884	-1.314378	0.916748
6	0.479718	-0.704622	-1.252934
1.2 补全缺失值

除了将缺失值直接过滤掉,还可以通过fillna方法来补全。
a. 使用常数来替代缺失值:

df
	0			1			2
0	-0.049375	NaN			NaN
1	-0.557540	NaN			NaN
2	-0.079590	NaN			1.016858
3	0.035582	NaN			0.562665
4	1.023047	0.485505	-0.086212
5	0.315884	-1.314378	0.916748
6	0.479718	-0.704622	-1.252934
df.fillna(0) # 原数据未改变
	0			1			2
0	-0.049375	0.000000	0.000000
1	-0.557540	0.000000	0.000000
2	-0.079590	0.000000	1.016858
3	0.035582	0.000000	0.562665
4	1.023047	0.485505	-0.086212
5	0.315884	-1.314378	0.916748
6	0.479718	-0.704622	-1.252934

b. 可以为不同列设定不同的填充值:

df.fillna({
   1: 0.5, 2: 0})
	0			1			2
0	-0.049375	0.500000	0.000000
1	-0.557540	0.500000	0.000000
2	-0.079590	0.500000	1.016858
3	0.035582	0.500000	0.562665
4	1.023047	0.485505	-0.086212
5	0.315884	-1.314378	0.916748
6	0.479718	-0.704622	-1.252934

c. fillna返回的是一个新对象,原对象不变,也可以修改已经存在的对象:

df.fillna(0, inplace=True) # 修改原数据

d. 支持插值法填充

df = pd.DataFrame(np.random.randn(6, 3))
df.iloc[2:, 1] = NA
df.iloc[4:, 2] = NA
df
	0			1			2
0	0.951068	0.878024	0.837684
1	0.231418	-1.218248	-0.986771
2	1.115496	NaN			0.536248
3	-1.295515	NaN			-1.474961
4	0.101957	NaN			NaN
5	-2.015696	NaN			NaN
df.fillna(method='ffill') # 向前填充,bfill向后填充
	0			1			2
0	0.951068	0.878024	0.837684
1	0.231418	-1.218248	-0.986771
2	1.115496	-1.218248	0.536248
3	-1.295515	-1.218248	-1.474961
4	0.101957	-1.218248	-1.474961
5	-2.015696	-1.218248	-1.474961
df.fillna(method='ffill', limit=2) # 向前填充两个数据
	0			1			2
0	0.951068	0.878024	0.837684
1	0.231418	-1.218248	-0.986771
2	1.115496	-1.218248	0.536248
3	-1.295515	-1.218248	-1.474961
4	0.101957	NaN			-1.474961
5	-2.015696	NaN			-1.474961

e. 还可以使用统计学数据来填充,如平均值/中位数等:

data = pd.Series([1., NA, 3.5, NA, 7])
data
0    1.0
1    NaN
2    3.5
3    NaN
4    7.0
dtype: float64
data.fillna(data.mean())
0    1.000000
1    3.833333
2    3.500000
3    3.833333
4    7.000000
dtype: float64
2. 数据转换
2.1 删除重复值

a. DataFrame 的duplicated方法返回的是一个布尔值Series,反映每一行是否存在与之前出现过的行相同的情况:

data = pd.DataFrame({
   'k1': ['one', 'two'] * 3 + ['two'],
                    'k2': [1, 1, 2, 3, 3, 4, 4]})
data
	k1	k2
0	one	1
1	two	1
2	one	2
3	two	3
4	one	3
5	two	4
6	two	4
data.duplicated()
0    False
1    False
2    False
3    False
4    False
5    False
6     True
dtype: bool

b. drop_duplicates 返回的是DataFrame,内容是duplicated返回数组中为False的部分,即删除了重复行

data.drop_duplicates() # 去除重复行
k1	k2
0	one	1
1	two	1
2	one	2
3	two	3
4	one	3
5	two	4

c. 可以基于特定的列去删除数据:

data['v1'] = range(7)
data
	k1	k2	v1
0	one	1	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值