前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python数据处理

python数据处理

作者头像
andrew_a
发布2019-12-25 14:41:19
1.4K0
发布2019-12-25 14:41:19
举报

很久没有更新文章了, 在这里分享一下关于数据处理的 步骤,方法供大家参考。

数据处理的基本内容主要包括数据清洗,数据抽取,数据交换,和数据计算等。

一、数据清洗

在数据分析的时候,原始数据或多或少都会存在大量的不完整、不一致,等异常的数据,会严重影响到数据分析的工作。经常遇到的数据清洗大都是处理缺失数据,清除无意义的信息。比如说删除原始数据集中的无关数据、重复数据,平滑噪声数据,筛选出与分析内容无关的数据,处理缺失值,异常值等。

1)重复值的处理

python中利用Pandas模块中去掉重复数据:

a) 利用Dataframe中的duplicated方法返回一个布尔类型的Series,显示是否有重复行,没有显示为FALSE, 有重复的重二行数据起显示为TRUE.

b) 在利用DataFrame中的drop_duplicates返回一个移除了重复行的DataFrame. 只保留一行数据。

代码语言:javascript
复制
f1.duplicated(subset=None, keep='first')
  • subset: 用于识别重复的列标签或者是列标签序列,默认为所有列标签
  • keep='first': 表示除了第一次出现外,其余相同数据都被标记为重复
  • keep='last': 表示除了最后一次出现外,其余相同数据都被标记为重复
  • keep=False: 所有相同数据都被标记为重复
代码语言:javascript
复制
df.drop_duplicates(subset=None, keep='first', inplace=False)

例:

代码语言:javascript
复制
# 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.如下例所示:

代码语言:javascript
复制
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) 缺失值的处理

对于缺失值的处理方式有数据对齐,删除对应行、不处理几种方法,我们通过一下几个例子进行缺失值的处理。

  • dropna(): 删除数据为空所对应的行
代码语言:javascript
复制
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(): 用其他数值代替NaN
代码语言:javascript
复制
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'): 用前一个数据值代替NaN
代码语言:javascript
复制
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'): 用后一个数据值代替NaN,可以用limit限制每列可以代替NaN的数目
代码语言:javascript
复制
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()): 用平均数代替NaN,除了平均数还可以是中位数等其他的统计来代替。
代码语言:javascript
复制
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({'列名 1':'值 1','列名 2':'值 2' }):传入一个字典给不同列填 充不同的值
代码语言:javascript
复制
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)字段抽取

字段抽取指的是抽取某列上指定位置的数据作为新的列

代码语言:javascript
复制
slice(start, stop)
start: 开始位置
stop:结束位置

例抽取电话的前三列:

代码语言:javascript
复制
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,拆分已有的字符串

代码语言:javascript
复制
split(sep,n,expand=False)
  • sep:用于分割字符串的分割符
  • n: 表示分割后新增的列数
  • expand: 表示是否展开为数据框,默认为False

注意:

返回值:expand为True,返回DataFrame; expand为False,返回Series.

代码语言:javascript
复制
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) 重置索引

重置索引是指定某列为索引,以便对其他数据进行操作

代码语言:javascript
复制
df.set_index('列名')

例:

代码语言:javascript
复制
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)记录抽取

抽取数据中满足某一条件的数据

代码语言:javascript
复制
df[condition]

condition 表示过滤条件

返回值:DataFrame

常用的condition类型:

  • 比较运算:==,>, <, >=, <=, !=,例如df[df.comments >1000]
  • 范围运算:between(left, right),例df[df.comments.between(10, 100)]
  • 字符匹配:str.contains(patten, na=False), 例如:df[df.title.str.contains('电台', na=False)]
  • 逻辑运算:&(逻辑与),|(逻辑或),not(取反)

例:

代码语言:javascript
复制
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)随机抽取

随机抽样是指随机从数据中按照一定的行数或者比例抽取数据

代码语言:javascript
复制
np.random.randint(start, end, num)
  • start:范围的开始值
  • end: 范围的结束值
  • num: 表示抽样个数
  • 返回值:行的索引值序列

例:

代码语言:javascript
复制
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[行标签:列标签]

代码语言:javascript
复制
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[行索引号, 列索引号]

代码语言:javascript
复制
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的用法

例:

代码语言:javascript
复制
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

先更新到这里~~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫scrapy 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档