很久没有更新文章了, 在这里分享一下关于数据处理的 步骤,方法供大家参考。
数据处理的基本内容主要包括数据清洗,数据抽取,数据交换,和数据计算等。
一、数据清洗
在数据分析的时候,原始数据或多或少都会存在大量的不完整、不一致,等异常的数据,会严重影响到数据分析的工作。经常遇到的数据清洗大都是处理缺失数据,清除无意义的信息。比如说删除原始数据集中的无关数据、重复数据,平滑噪声数据,筛选出与分析内容无关的数据,处理缺失值,异常值等。
1)重复值的处理
python中利用Pandas模块中去掉重复数据:
a) 利用Dataframe中的duplicated方法返回一个布尔类型的Series,显示是否有重复行,没有显示为FALSE, 有重复的重二行数据起显示为TRUE.
b) 在利用DataFrame中的drop_duplicates返回一个移除了重复行的DataFrame. 只保留一行数据。
f1.duplicated(subset=None, keep='first')
df.drop_duplicates(subset=None, keep='first', inplace=False)
例:
# padans去除重复数据
f1 = pd.DataFrame({'age':[12, 7, 34, 7, 10,7], 'name':['A','C','B', 'C','D','C']})
print(f1)
age name
0 12 A
1 7 C
2 34 B
3 7 C
4 10 D
5 7 C
f1.duplicated()
0 False
1 False
2 False
3 True
4 False
5 True
dtype: bool
f1
f1.drop_duplicates('name')
age name
0 12 A
1 7 C
2 34 B
4 10 D
上面的第三行和第五行数据与前面的数据是重复的,去掉重复数据后第三行和第五行均被删除。
2)缺失值处理
在做数据统计时,缺失的数据可能会产生有偏估计,使得样本数据不能很好的将总体数据表达出来,并且现实中的数据很多都是包含缺失值。
处理缺失值有两步骤:缺失值的识别,缺失数据的处理。
a) 缺失值的识别
Padans使用浮点值NaN表示浮点和非浮点数组里的缺失数据,用isnull() ,notnull()来判断是否有缺失值. isnull()判断如果有缺失值则返回True,没有返回False.如下例所示:
df = pd.read_excel("./student_score.xlsx",sheet_name='Sheet2')
print(df.head(5))
# 缺失数据的识别
print(df.isnull())
print(df.notnull())
学号 姓名 英语 数分 高代 解几
0 2308024241 成龙 76 40.0 23.0 60
1 2308024244 周怡 66 47.0 47.0 44
2 2308024251 张波 85 NaN 45.0 60
3 2308024249 朱浩 65 72.0 62.0 71
4 2308024219 封印 73 61.0 47.0 46
学号 姓名 英语 数分 高代 解几
0 False False False False False False
1 False False False False False False
2 False False False True False False
3 False False False False False False
4 False False False False False False
5 False False False False False False
学号 姓名 英语 数分 高代 解几
0 True True True True True True
1 True True True True True True
2 True True True False True True
3 True True True True True True
4 True True True True True True
5 True True True True True True
b) 缺失值的处理
对于缺失值的处理方式有数据对齐,删除对应行、不处理几种方法,我们通过一下几个例子进行缺失值的处理。
df1 = pd.read_excel("./student_score.xlsx",sheet_name='Sheet2')
print(df.head(5))
df1.dropna()
学号 姓名 英语 数分 高代 解几
0 2308024241 成龙 76 40.0 23.0 60
1 2308024244 周怡 66 47.0 47.0 44
2 2308024251 张波 85 NaN 45.0 60
3 2308024249 朱浩 65 72.0 62.0 71
4 2308024219 封印 73 61.0 47.0 46
学号 姓名 英语 数分 高代 解几
0 2308024241 成龙 76 40.0 23.0 60
1 2308024244 周怡 66 47.0 47.0 44
3 2308024249 朱浩 65 72.0 62.0 71
4 2308024219 封印 73 61.0 47.0 46
如上例,姓名为张波的这一行数据,因为有空值被删除了。在这里可以传入指定参数df.dropna(how='all'), 表示只有行里的数据全部为空的时候才删除。如果有一列中的数据为空,想要删除这一列数据,可以传入axis=1,既df.dropna(how='all', axis=1), 现实处理数据的时候删除空数据多会影响分析结果,一般不会作出删除操作,我们可以对数据进行填补。
df.fillna('?')
学号 姓名 英语 数分 高代 解几
0 2308024241 成龙 76 40 23 60
1 2308024244 周怡 66 47 47 44
2 2308024251 张波 85 ? 45 60
3 2308024249 朱浩 65 72 62 71
4 2308024219 封印 73 61 47 46
5 2308024201 迟培 60 71 76 71
6 2308024347 李华 67 61 65 78
7 2308024307 陈田 76 69 ? 69
8 2308024326 余皓 66 65 61 71
9 2308024219 封印 73 61 47 46
上例使用了"?"代替缺失值.
df.fillna(method='pad')
学号 姓名 英语 数分 高代 解几
0 2308024241 成龙 76 40.0 23.0 60
1 2308024244 周怡 66 47.0 47.0 44
2 2308024251 张波 85 47.0 45.0 60
3 2308024249 朱浩 65 72.0 62.0 71
4 2308024219 封印 73 61.0 47.0 46
5 2308024201 迟培 60 71.0 76.0 71
6 2308024347 李华 67 61.0 65.0 78
7 2308024307 陈田 76 69.0 65.0 69
8 2308024326 余皓 66 65.0 61.0 71
9 2308024219 封印 73 61.0 47.0 46
上列使用同一列的上一个数据进行替代。
df.fillna(method='bfill')
学号 姓名 英语 数分 高代 解几
0 2308024241 成龙 76 40.0 23.0 60
1 2308024244 周怡 66 47.0 47.0 44
2 2308024251 张波 85 72.0 45.0 60
3 2308024249 朱浩 65 72.0 62.0 71
4 2308024219 封印 73 61.0 47.0 46
5 2308024201 迟培 60 71.0 76.0 71
6 2308024347 李华 67 61.0 65.0 78
7 2308024307 陈田 76 69.0 61.0 69
8 2308024326 余皓 66 65.0 61.0 71
9 2308024219 封印 73 61.0 47.0 46
df.fillna(df.mean())
学号 姓名 英语 数分 高代 解几
0 2308024241 成龙 76 40.000000 23.000000 60
1 2308024244 周怡 66 47.000000 47.000000 44
2 2308024251 张波 85 60.777778 45.000000 60
3 2308024249 朱浩 65 72.000000 62.000000 71
4 2308024219 封印 73 61.000000 47.000000 46
5 2308024201 迟培 60 71.000000 76.000000 71
6 2308024347 李华 67 61.000000 65.000000 78
7 2308024307 陈田 76 69.000000 52.555556 69
8 2308024326 余皓 66 65.000000 61.000000 71
9 2308024219 封印 73 61.000000 47.000000 46
df.fillna({'数分':100,'高代':0})
学号 姓名 英语 数分 高代 解几
0 2308024241 成龙 76 40.0 23.0 60
1 2308024244 周怡 66 47.0 47.0 44
2 2308024251 张波 85 100.0 45.0 60
3 2308024249 朱浩 65 72.0 62.0 71
4 2308024219 封印 73 61.0 47.0 46
5 2308024201 迟培 60 71.0 76.0 71
6 2308024347 李华 67 61.0 65.0 78
7 2308024307 陈田 76 69.0 0.0 69
8 2308024326 余皓 66 65.0 61.0 71
9 2308024219 封印 73 61.0 47.0 46
二、数据抽取
1)字段抽取
字段抽取指的是抽取某列上指定位置的数据作为新的列
slice(start, stop)
start: 开始位置
stop:结束位置
例抽取电话的前三列:
df_sl = pd.read_excel('./tel_ip.xls', sheet_name='Sheet4')
df_sl.head()
学号 电话 IP
0 2308024241 1.892225e+10 221.205.98.55
1 2308024244 1.352226e+10 183.184.226.205
2 2308024251 1.342226e+10 221.205.98.55
3 2308024249 1.882226e+10 222.31.51.200
4 2308024219 1.892225e+10 120.207.64.3
df_sl['电话']=df_sl['电话'].astype(str) # 将电话列转化为字符串格式
# df_sl['电话']
bands= df_sl['电话'].str.slice(0,3) # 抽取手机的前三位,查看时哪个运营商
bands
0 189
1 135
2 134
3 188
4 189
5 nan
6 138
7 133
8 189
9 133
10 189
11 199
12 199
13 199
14 199
15 199
16 199
17 199
18 199
19 199
Name: 电话, dtype: object
2)字段拆分
指的时按照指定的字符sep,拆分已有的字符串
split(sep,n,expand=False)
注意:
返回值:expand为True,返回DataFrame; expand为False,返回Series.
df_sl = pd.read_excel('./tel_ip.xls', sheet_name='Sheet4')
df_sl.head()
df_sl['IP'].str.strip() # 将Ip转化为str,在删除首尾空格
new_df = df_sl['IP'].str.split('.', 1,True) # 按照第一个”.“分成两列, 1表示新增的数列
new_df.columns =['IP1', 'IP2-4']
new_df
IP1 IP2-4
0 221 205.98.55
1 183 184.226.205
2 221 205.98.55
3 222 31.51.200
4 120 207.64.3
5 222 31.51.200
6 222 31.59.220
7 221 205.98.55
8 183 184.230.38
9 221 205.98.55
10 183 184.230.38
11 183 184.230.39
12 185 184.230.40
13 183 154.230.41
14 183 184.231.42
15 183 154.230.43
16 173 184.230.44
17 NaN NaN
18 183 184.230.4
19 153 144.230.7
3) 重置索引
重置索引是指定某列为索引,以便对其他数据进行操作
df.set_index('列名')
例:
import pandas as pd
df = pd.DataFrame({'age':pd.Series([26, 18, 24,78, 45]), 'name':pd.Series(['Jone', 'Tom', 'Slicy','Jerry','Gun'])})
df1 = df.set_index('name') # 以name列为新的索引
print(df1)
age
name
Jone 26
Tom 18
Slicy 24
Jerry 78
Gun 45
df1.ix['Tom'] # 提取Tome用户的信息
age 18
Name: Tom, dtype: int64
注意:
上例中的ix函数时通过行标签或行号索引某一行数据的。
4)记录抽取
抽取数据中满足某一条件的数据
df[condition]
condition 表示过滤条件
返回值:DataFrame
常用的condition类型:
例:
import pandas as pd
df_sl = pd.read_excel('./tel_ip.xls', sheet_name='Sheet4')
df_sl.head()
df_sl[df_sl.电话==13322252452]
学号 电话 IP
7 2308024307 1.332225e+10 221.205.98.55
9 2308024320 1.332225e+10 221.205.98.55
df_sl[df_sl.电话 >19200000000]
学号 电话 IP
15 2308024421 1.993421e+10 183.154.230.43
16 2308024433 1.993421e+10 173.184.230.44
17 2308024428 1.993421e+10 NaN
18 2308024402 1.993421e+10 183.184.230.4
19 2308024422 1.993421e+10 153.144.230.7
df_sl[df_sl.电话.between(18800000000,19000000000)]
学号 电话 IP
0 2308024241 1.892225e+10 221.205.98.55
3 2308024249 1.882226e+10 222.31.51.200
4 2308024219 1.892225e+10 120.207.64.3
df_sl[df_sl.IP.str.contains('59.', na=False)] # 字符匹配
学号 电话 IP
6 2308024347 1.382225e+10 222.31.59.220
df_sl[df_sl.电话>= 13822254373]
学号 电话 IP
0 2308024241 1.892225e+10 221.205.98.55
3 2308024249 1.882226e+10 222.31.51.200
4 2308024219 1.892225e+10 120.207.64.3
df_sl[(df_sl.电话>= 13322259938) & (df_sl.电话< 18822254373)]
学号 电话 IP
1 2308024244 1.352226e+10 183.184.226.205
2 2308024251 1.342226e+10 221.205.98.55
6 2308024347 1.382225e+10 222.31.59.220
5)随机抽取
随机抽样是指随机从数据中按照一定的行数或者比例抽取数据
np.random.randint(start, end, num)
例:
import numpy as np
r = np.random.randint(0, 10,3) # 从索引值为0~10中随机抽取三个数
print(r)
df_sl.loc[r,:] # 抽取r行数据,也可以写成df.loc[r]
[8 5 8]
学号 电话 IP
8 2308024326 1.892226e+10 183.184.230.38
5 2308024201 NaN 222.31.51.200
8 2308024326 1.892226e+10 183.184.230.38
6)通过索引抽取数据
a) 通过索引名(标签)选取数据:
df.loc[行标签:列标签]
df_sl.loc[2308024241:2308024251 ] # 选取学号在2308024241 到 2308024251之间的数据
学号 电话 IP
2308024241 1.892225e+10 221.205.98.55
2308024244 1.352226e+10 183.184.226.205
2308024251 1.342226e+10 221.205.98.55
df_sl.loc[:, '电话'] # 选取”电话“列的数据
学号
2308024241 1.892225e+10
2308024244 1.352226e+10
2308024251 1.342226e+10
2308024249 1.882226e+10
2308024219 1.892225e+10
2308024201 NaN
2308024347 1.382225e+10
df_sl.loc[[2308024249,2308024422]] # 抽取2308024422 ,2308024249两行数据
学号 电话 IP
2308024249 1.882226e+10 222.31.51.200
2308024422 1.993421e+10 153.144.230.7
注意:
当抽取多行数据的时候,含的索引必须是列表的形式,不能之间以逗号隔开。
b) 使用索引号选取数据:
df.iloc[行索引号, 列索引号]
df_sl.iloc[4, 0] # 选取第5行,第一列数据,返回单个数值
18922253721.0
df_sl.iloc[[0, 2], :] # 选取第一行和第三行的数据
学号 电话 IP
2308024241 1.892225e+10 221.205.98.55
2308024251 1.342226e+10 221.205.98.55
# 选取第一行到第三行的数据(不包含第三行数据)
df_sl.iloc[0:2, :]
学号 电话 IP
2308024241 1.892225e+10 221.205.98.55
2308024244 1.352226e+10 183.184.226.205
# 选取第二列所有数据,返回一个Series
df_sl.iloc[:,1]
学号
2308024241 221.205.98.55
2308024244 183.184.226.205
2308024251 221.205.98.55
2308024249 222.31.51.200
2308024219 120.207.64.3
2308024201 222.31.51.200
.......
2308024422 153.144.230.7
Name: IP, dtype: object
# 选取第二行所有数据,返回值为一个Seeries
df_sl.iloc[1, :]
电话 1.35223e+10
IP 183.184.226.205
Name: 2308024244, dtype: object
注意:
loc为字符串索引(索引名索引),iloc为整型索引(只能是索引号索引);ix是更广义的切片方式,它是loc,和iloc的结合,它可以根据索引号或者索引名索引,但是当索引名是int类型是,只能用索引名索引,不可以用索引号索引。
c) df.ix的用法
例:
import pandas as pd
index_loc = ['a', 'b'] # 索引名为字符串
index_iloc = [1,2] # 索引名为数字
data = [[1,2,3,4],[5,6,7,8]]
columns = ['one', 'two', 'three','four'] # 列名
df1=pd.DataFrame(data=data, index=index_loc, columns=columns)
df2=pd.DataFrame(data=data, index=index_iloc, columns=columns)
df1.head() # 索引名为字符串
one two three four
a 1 2 3 4
b 5 6 7 8
df1.ix['a']
one 1
two 2
three 3
four 4
Name: a, dtype: int64
df1.ix[0]
one 1
two 2
three 3
four 4
Name: a, dtype: int64
df2.head() # 索引名为int
one two three four
1 1 2 3 4
2 5 6 7 8
df2.ix[1]
one 1
two 2
three 3
four 4
Name: 1, dtype: int64
df2.ix[0] # 会报错
try:
-> 2525 return self._engine.get_loc(key)
2526 except KeyError:
.......
KeyError: 0
先更新到这里~~
本文分享自 Python爬虫scrapy 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!