python数据处理

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

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

一、数据清洗

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

1)重复值的处理

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

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

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

f1.duplicated(subset=None, keep='first')
  • subset: 用于识别重复的列标签或者是列标签序列,默认为所有列标签
  • keep='first': 表示除了第一次出现外,其余相同数据都被标记为重复
  • keep='last': 表示除了最后一次出现外,其余相同数据都被标记为重复
  • keep=False: 所有相同数据都被标记为重复
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) 缺失值的处理

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

  • dropna(): 删除数据为空所对应的行
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
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
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的数目
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,除了平均数还可以是中位数等其他的统计来代替。
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' }):传入一个字典给不同列填 充不同的值
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)
  • 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类型:

  • 比较运算:==,>, <, >=, <=, !=,例如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(取反)

例:

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)
  • 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(python_scrapy)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Matplotlib绘制的27个常用图(附对应代码实现,牛!)

    https://nbviewer.jupyter.org/github/matplotlib/AnatomyOfMatplotlib/blob/master/A...

    1480
  • 盘点Python 63个内置函数

    判断对象是否可以被调用,能被调用的对象就是一个callable 对象,比如函数 str, int 等都是可被调用的,但是例子4 中xiaoming这个实例是不可...

    1480
  • 即学即用的 30 段 Python 实用代码

    原标题 | 30 Helpful Python Snippets That You Can Learn in 30 Seconds or Less

    1480
  • Python要点总结,我使用了100个小例子!

    类型检查是一个验证和施加类型约束的过程,编译器或解释器通常在编译或运行阶段做类型检查。例如,你不能拿一个string类型值除以浮点数。

    1480
  • 从Excel到Python:最常用的36个Pandas函数

    本文涉及pandas最常用的36个函数,通过这些函数介绍如何完成数据生成和导入、数据清洗、预处理,以及最常见的数据分类,数据筛选,分类汇总,透视等最常见的操作。

    统计学家
  • Pandas中文官档 基础用法1

    head() 与 tail() 用于快速预览 Series 与 DataFrame,默认显示 5 条数据,也可以指定要显示的数量。

    double
  • 4 个妙招增强 Jupyter Notebook 功能

    Jupyter Notebook 是所有开发者共享工作的神器,它为共享 Notebooks 提供了一种便捷方式:结合文本、代码和图更快捷地将信息传达给受众。目前...

    1480
  • Pandas数据结构之DataFrame常见操作

    DataFrame 就像带索引的 Series 字典,提取、设置、删除列的操作与字典类似:

    double
  • 部署机器学习非常困难,并将一直如此...

    机器学习技术正在令我们的生活发生日新月异的变化。对于学术界来说,科研人员的工作往往止步于原型算法的研制。然而,在真实的工业生产场景下,将原型机器学习算法部署到应...

    统计学家
  • 7个Python特殊技巧,助力你的数据分析工作之路

    该工具效果明显。下图展示了调用 df.profile_report() 这一简单方法的结果:

    1480

扫码关注云+社区

领取腾讯云代金券