美文网首页大数据 爬虫Python AI SqlPython学习分享程序员
Python数据清洗80%的工作量,看这篇就够了

Python数据清洗80%的工作量,看这篇就够了

作者: 烟雨丿丶蓝 | 来源:发表于2019-05-27 14:46 被阅读29次
    image

    干净整洁的数据是后续进行研究和分析的基础。数据科学家们会花费大量的时间来清理数据集,毫不夸张地说,数据清洗会占据他们80%的工作时间,而真正用来分析数据的时间只占到20%左右。

    所以,数据清洗到底是在清洗些什么?

    通常来说,你所获取到的原始数据不能直接用来分析,因为它们会有各种各样的问题,如包含无效信息,列名不规范、格式不一致,存在重复值,缺失值,异常值等.....

    本文会给大家介绍如何用Python中自带的 PandasNumPy 库进行数据清洗。在正式讲解之前,先简单介绍一下这两个非常好用的库。

    Pandas 的名称来自于 P anel data 和Python数据分析 data analysis ,是Python的一个数据分析包,最初由AQR Capital Management于2008年4月开发,被作为金融数据分析工具,为时间序列分析提供了很好的支持,并于2009年底开源出来。

    NumPyNumeric Python 的缩写,是Python的一种开源的数值计算扩展,可用来存储和处理大型矩阵 matrix ,比Python自身的嵌套列表结构要高效的多,提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库,专为进行严格的数字处理而产生。

    目录

    一、了解数据

    二、清洗数据

    去除不需要的行、列

    重新命名列

    重新设置索引

    用字符串操作规范列

    用函数规范列

    删除重复数据

    填充缺失值

    三、总结

    【注】为了清晰直观地展示数据清洗操作,本文会用到几个不同的数据集,重点是方法的讲解。

    【工具】Python 3

    一、了解数据

    拿到一个全新的数据集,应该从哪里入手?

    没错,我们需要先了解数据,看看它长什么样子。这里用 tushare.pro 上面的日线行情数据进行展示,以浦发银行(600000.SH)为例。常用的方法和属性如下:

    **.head()**
    
    **.tail()**
    
    **.shape**
    
    **.columns**
    
    **.info()**
    
    **.describe()**
    
    **.value_counts()**
    

    首先,获取数据:

    importpandasaspd
    
    importnumpyasnp
    
    importmatplotlib.pyplotasplt
    
    importtushareasts
    
    pd.set_option('display.max_columns',100)# 设置显示数据的最大列数,防止出现省略号…,导致数据显示不全
    
    pd.set_option('expand_frame_repr',False)# 当列太多时不自动换行
    
    pro = ts.pro_api()
    
    df = pro.daily(ts_code='600000.SH', start_date='20190401', end_date='20190430')
    

    **.head() ** 查看前n行数据,默认值是5

    df.head()
    
    Out[1]:
    
    ts_codetrade_dateopenhighlowclosepre_closechangepct_chgvolamount
    
    0  600000.SH20190430  11.7012.0911.7011.9711.480.494.26831234747.381466714.710
    
    1  600000.SH20190429  11.3511.5411.3411.4811.320.161.4134385869.38442046.727
    
    2  600000.SH20190426  11.4311.5611.2811.3211.54-0.22-1.9064424695.81485267.261
    
    3  600000.SH20190425  11.5611.6911.4811.5411.62-0.08-0.6885408761.29473973.527
    
    4  600000.SH20190424  11.7611.7711.5111.6211.70-0.08-0.6838382011.08444929.313
    

    **.tail() ** 查看后n行数据,默认值是5

    df.tail()
    
    Out[2]:
    
    ts_codetrade_dateopenhighlowclosepre_closechangepct_chgvolamount
    
    16  600000.SH20190408  11.7911.9611.6511.7211.710.010.0854778703.73920513.531
    
    17  600000.SH20190404  11.5511.7111.5411.7111.500.211.8261752325.27876099.547
    
    18  600000.SH20190403  11.3711.5411.3411.5011.440.060.5245502710.29575799.446
    
    19  600000.SH20190402  11.5011.5211.4111.4411.440.000.0000467147.10534896.810
    
    20  600000.SH20190401  11.3611.5211.2911.4411.280.161.4184706374.05808657.530
    

    **.shape ** 查看数据维数

    df.shape
    
    Out[3]: (21, 11)
    

    **.columns ** 查看所有列名

    df.columns
    
    Out[4]:
    
    Index(['ts_code','trade_date','open','high','low','close','pre_close',
    
    'change','pct_chg','vol','amount'],
    
    dtype='object')
    

    **.info() ** 查看索引、数据类型和内存信息

    df.info()
    
    RangeIndex:21entries,0to20
    
    Data columns (total11columns):
    
    ts_code21non-nullobject
    
    trade_date21non-nullobject
    
    open21non-nullfloat64
    
    high21non-nullfloat64
    
    low21non-nullfloat64
    
    close21non-nullfloat64
    
    pre_close21non-nullfloat64
    
    change21non-nullfloat64
    
    pct_chg21non-nullfloat64
    
    vol21non-nullfloat64
    
    amount21non-nullfloat64
    
    dtypes: float64(9),object(2)
    
    memory usage:1.9+ KB
    

    **.describe() ** 查看每列数据的基本统计值,包括计数值、均值、标准差、最小最大值、1/4、1/2、3/4分位数。

    df.describe()
    
    Out[7]:
    
    openhighlowclosepre_closechangepct_chgvolamount
    
    count21.00000021.00000021.00000021.00000021.00000021.00000021.0000002.100000e+01  2.100000e+01
    
    mean11.63047611.77761911.52428611.63714311.6042860.0328570.2962525.734931e+05  6.704836e+05
    
    std0.2153480.2289300.1848400.2075120.2067990.1932131.6710992.333355e+05  2.792896e+05
    
    min11.35000011.52000011.28000011.32000011.280000-0.300000-2.4979002.627369e+05  3.017520e+05
    
    25%    11.47000011.56000011.41000011.48000011.470000-0.060000-0.5199004.102754e+05  4.739735e+05
    
    50%    11.56000011.75000011.48000011.54000011.5400000.0000000.0000005.027103e+05  5.757994e+05
    
    75%    11.76000011.99000011.65000011.72000011.7100000.1000000.8396007.050917e+05  8.161270e+05
    
    max12.02000012.20000011.88000012.01000012.0100000.4900004.2683001.234747e+06  1.466715e+06
    

    .value_counts() 查看Series对象的唯一值和计数值

    df['close'].value_counts(dropna=False)
    
    Out[8]:
    
    11.482
    
    11.472
    
    11.712
    
    11.542
    
    11.912
    
    11.442
    
    11.721
    
    11.951
    
    11.701
    
    11.321
    
    11.491
    
    12.011
    
    11.621
    
    11.501
    
    11.971
    
    Name:close, dtype:int64
    

    如果上面这些操作还不够直观的话,就作图看看,需要先导入Python可视化库 matplotlib , 为了规范代码书写,统一写在了最前面。

    直方图
    df['close'].plot(kind='hist', rot=0)

    plt.show()

    image

    箱型图

    df.boxplot(column='close',by='ts_code', rot=0)

    plt.show()

    image

    散点图

    df.plot(kind='scatter', x='close', y='pre_close', rot=0)

    plt.show()


    image

    二、清洗数据

    了解数据集之后,我们就可以开始对数据集进行清洗了,前面提到通常要处理的问题有包含无效信息,列名不规范、格式不一致,存在重复值,缺失值,异常值等,下面我们一个一个来看。

    01

    去除不需要的行、列

    在分析一个数据集的时候,很多信息其实是用不到的,因此,需要去除不必要的行或列。这里以csv文件为例,在导入的时候就可以通过设置 pd.read_csv() 里面的参数来实现这个目的。

    先来感受一下官方文档中给出的详细解释,里面的参数是相当的多,本文只介绍比较常用的几个,感兴趣的话,可以好好研究一下文档,这些参数还是非常好用的,能省去很多导入后整理的工作。

    image

    header 】默认header=0,即将文件中的0行作为列名和数据的开头,但有时候0行的数据是无关的,我们想跳过0行,让1行作为数据的开头,可以通过将header设置为1来实现。

    usecols 】根据列的位置或名字,如[0,1,2]或[‘a’, ‘b’, ‘c’],选出特定的列。

    nrows 】要导入的数据行数,在数据量很大、但只想导入其中一部分时使用。

    如果你对Python编程感兴趣,那么记得来小编的Python学习扣群:1017759557,这里有资源共享,技术解答,大家可以在一起交流Python编程经验,还有小编整理的一份Python学习教程,希望能帮助大家更好的学习python。

    获取数据:

    从NYC OpenData网站下载csv格式原始数据


    image

    数据样本如下:


    image

    导入数据,只选取前100行和特定几列。

    subset_columns= ['Job #','Doc #','Borough','Initial Cost','Total Est. Fee']
    
    df = pd.read_csv('文件路径', nrows=100, usecols=subset_columns)
    
    df.head()
    
    Out[15]:
    
    Job#  Doc #   Borough Initial Cost Total Est. Fee
    
    04202917941QUEENS$2000.00$100.00
    
    14202918011QUEENS$15000.00$151.50
    
    23406441281BROOKLYN$44726.00$234.00
    
    34216854391QUEENS$0.00$243.00
    
    44216779742QUEENS$105000.00$1275.60
    

    再看一下将header设置为1的效果,但这里其实不需要这么做,因为0行数据是有用的。

    df= pd.read_csv('文件路径', nrows=100, header=1)
    
    df.head()
    
    Out[15]:
    
    04202917941QUEENS$2000.00$100.00
    
    14202918011QUEENS$15000.00$151.50
    
    23406441281BROOKLYN$44726.00$234.00
    
    34216854391QUEENS$0.00$243.00
    
    44216779742QUEENS$105000.00$1275.60
    

    如果在数据导入之后,还想删除某些行和列,可以用 **.drop() ** 方法。

    先创建一个列表list,把不需要的列名放进去,再调用 .drop() 方法,参数 axis1 时代表列,为 0 时代表行,参数 inplace=True 表示不创建新的对象,直接对原始对象进行修改。这里我们删除前两列。

    to_drop= ['Job #','Doc #']
    
    df.drop(to_drop, axis=1, inplace=True)
    
    df.head()
    
    Out[22]:
    
    Borough Initial Cost Total Est. Fee
    
    0QUEENS$2000.00$100.00
    
    1QUEENS$15000.00$151.50
    
    2BROOKLYN$44726.00$234.00
    
    3QUEENS$0.00$243.00
    
    4QUEENS$105000.00$1275.60
    

    02

    重新命名列

    当原始数据的列名不好理解,或者不够简洁时,可以用 .rename() 方法进行修改。这里我们把英文的列名改成中文,先创建一个字典,把要修改的列名定义好,然后调用 rename() 方法。

    new_names = {'Borough':'区','Initial Cost':'初始成本','Total Est. Fee':'总附加费用'}
    
    df.rename(columns=new_names, inplace=True)
    
    df.head()
    
    Out[23]:
    
    区        初始成本     总附加费用
    
    0    QUEENS$2000.00$100.00
    
    1    QUEENS$15000.00$151.50
    
    2  BROOKLYN$44726.00$234.00
    
    3    QUEENS$0.00$243.00
    
    4    QUEENS$105000.00$1275.60
    

    03

    重新设置索引

    数据默认的索引是从0开始的有序整数,但如果想把某一列设置为新的索引,可以用 .set_index() 方法实现,在示例中我们把"区"这列设置为新索引。

    df.set_index('区', inplace=True)
    
    df.head()
    
    Out[24]:
    
    初始成本     总附加费用
    
    区
    
    QUEENS$2000.00$100.00
    
    QUEENS$15000.00$151.50
    
    BROOKLYN$44726.00$234.00
    
    QUEENS$0.00$243.00
    
    QUEENS$105000.00$1275.60
    

    04

    用字符串操作规范列

    字符串 str 操作是非常实用的,因为列中总是会包含不必要的字符,常用的方法如下:

    **lower()**
    
    **upper()**
    
    **capitalize()**
    
    **replace()**
    
    **strip()**
    
    **split()**
    
    **get()**
    
    **contains()**
    
    **find()**
    

    str.lower() 是把大写转换成小写,同理, str.upper() 是把小写转换成大写,将示例中用大写字母表示的索引转换成小写,效果如下:

    df.index = df.index.str.lower()
    
    df.head()
    
    Out[25]:
    
    初始成本     总附加费用
    
    区
    
    queens$2000.00$100.00
    
    queens$15000.00$151.50
    
    brooklyn$44726.00$234.00
    
    queens$0.00$243.00
    
    queens$105000.00$1275.60
    

    str.capitalize() 设置首字母大写

    df.index = df.index.str.capitalize()
    
    df.head()
    
    Out[26]:
    
    初始成本     总附加费用
    
    区
    
    Queens$2000.00$100.00
    
    Queens$15000.00$151.50
    
    Brooklyn$44726.00$234.00
    
    Queens$0.00$243.00
    
    Queens$105000.00$1275.60
    

    **str.replace('', '') ** 替换特定字符。这里把列中的美元符号去掉,替换成空字符。

    df['初始成本'] = df['初始成本'].str.replace('$','')
    
    df['总附加费用'] = df['总附加费用'].str.replace('$','')
    
    df.head()
    
    Out[27]:
    
    初始成本    总附加费用
    
    区
    
    Queens2000.00100.00
    
    Queens15000.00151.50
    
    Brooklyn44726.00234.00
    
    Queens0.00243.00
    
    Queens105000.001275.60
    

    **str.strip() ** 去除字符串中的头尾空格、以及\n \t

    df['初始成本'] = '   ' + df['初始成本']
    
    df['初始成本'][0]
    
    Out[28]: '   2000.00'
    
    df['初始成本'] = df['初始成本'].str.strip()
    
    df['初始成本'][0]
    
    Out[29]: '2000.00'
    

    **str.split('x') ** 使用字符串中的 'x' 字符作为分隔符,将字符串分隔成列表。这里将列中的值以 '.'进行分割,效果如下:

    df['总附加费用'] = df['总附加费用'].str.split('.')
    
    df.head()
    
    Out[30]:
    
    初始成本       总附加费用
    
    区
    
    Queens2000.00[100,00]
    
    Queens15000.00[151,50]
    
    Brooklyn44726.00[234,00]
    
    Queens0.00[243,00]
    
    Queens105000.00[1275,60]
    

    **str.get() ** 选取列表中某个位置的值。接着上面分割后的结果,我们用 str.get(0) 取出列表中前一个位置的数值,生成新的一列“总附加费用_整数”,即取出金额中的整数部分。

    df['总附加费用_整数'] = df['总附加费用'].str.get(0)

    df.head()
    
    Out[31]:
    
    初始成本       总附加费用 总附加费用_整数
    
    区
    
    Queens2000.00[100,00]100
    
    Queens15000.00[151,50]151
    
    Brooklyn44726.00[234,00]234
    
    Queens0.00[243,00]243
    
    Queens105000.00[1275,60]1275
    

    **str.contains() ** 判断是否存在某个字符,返回的是布尔值。这里判断一下"总附加费用_整数"列中是否包含字符'0'。

    df['总附加费用_整数'].str.contains('0')
    
    Out[33]:
    
    区
    
    QueensTrue
    
    QueensFalse
    
    BrooklynFalse
    
    QueensFalse
    
    QueensFalse
    

    str.find() 检测字符串中是否包含子字符串str,如果是,则返回该子字符串开始位置的索引值。示例中的'0'字符最开始出现的位置是1。

    df['总附加费用_整数'][0]
    
    Out[13]: '100'
    
    df['总附加费用_整数'][0].find('0')
    
    Out[14]: 1
    

    学完基本的字符串操作方法,我们来看一下如何结合 NumPy 来提高字符串操作的效率。

    获取数据,这里我们用一个新的数据集,下载链接如下,里面包含两个csv文件和一个txt文件:

    https://github.com/realpython/python-data-cleaning

    ① BL-Flickr-Images-Book.csv
    
    ② olympics.csv
    
    ③ university_towns.txt
    
    导入csv文件①,先观察一下"Place of Publication"这一列。
    
    df = pd.read_csv('文件路径')
    
    df['Place of Publication'].head(10)
    
    Out[38]:
    
    0London
    
    1London; Virtue & Yorston
    
    2London
    
    3London
    
    4London
    
    5London
    
    6London
    
    7pp.40. G. Bryan & Co: Oxford,1898
    
    8London]
    
    9London
    
    Name: PlaceofPublication, dtype:object
    

    我们发现,这一列中的格式并不统一,比如1行中的London; Virtue & Yorston,London后面的部分我们不需要,还有7行的pp. 40. G. Bryan & Co: Oxford, 1898,有效信息只是Oxford。

    再用 .tail(10) 方法观察这一列的最后十行:

    df['Place of Publication'].tail(10)
    
    Out[39]:
    
    8277New York
    
    8278London
    
    8279New York
    
    8280London
    
    8281Newcastle-upon-Tyne
    
    8282London
    
    8283Derby
    
    8284London
    
    8285Newcastle upon Tyne
    
    8286London
    
    Name: PlaceofPublication, dtype:object
    

    我们发现,8281行的Newcastle-upon-Tyne中间有连字符,但8285行却没有,这些都是要解决的格式不规范的问题。

    为了清洗这一列,我们可以将Pandas中的 .str() 方法与NumPy的 np.where 函数相结合, np.where 函数是Excel的IF()宏的矢量化形式,它的语法如下:

    >>> np.where(condition,then,else)
    

    如果 condition 条件为真,则执行 then ,否则执行 else 。这里的condition条件可以是一个类数组的对象,也可以是一个布尔表达式,我们也可以利用 np.where 函数嵌套多个条件进行矢量化计算和判断。

    >>> np.where(condition1, x1,
    
    np.where(condition2, x2,
    
    np.where(condition3, x3, ...)))
    

    下面的这个实例,就是同时嵌套两个条件解决上面提到的那两个字符串问题。思路是,如果字符串里面包含'London',就用'London'代替,这样可以去除其他冗余信息,否则,如果字符串里面包含'Oxford',则用'Oxford'代替,同时如果字符串里面包含符号'-',则用空格代替。

    pub = df['Place of Publication']
    
    london = pub.str.contains('London')
    
    oxford = pub.str.contains('Oxford')
    
    df['Place of Publication'] = np.where(london,'London',
    
    np.where(oxford,'Oxford',
    
    pub.str.replace('-',' ')))
    

    打印出前十行和后十行,结果如下,可以和整理前的数据进行对比。

    df['Place of Publication'].head(10)
    
    Out[42]:
    
    0London
    
    1London
    
    2London
    
    3London
    
    4London
    
    5London
    
    6London
    
    7Oxford
    
    8London
    
    9London
    
    Name: PlaceofPublication, dtype:object
    
    df['Place of Publication'].tail(10)
    
    Out[43]:
    
    8277New York
    
    8278London
    
    8279New York
    
    8280London
    
    8281Newcastle upon Tyne
    
    8282London
    
    8283Derby
    
    8284London
    
    8285Newcastle upon Tyne
    
    8286London
    
    Name: PlaceofPublication, dtype:object
    

    05
    用函数规范列

    在某些情况下,数据不规范的情况并不局限于某一列,而是更广泛地分布在整个表格中。因此,自定义函数并应用于整个表格中的每个元素会更加高效。用 applymap() 方法可以实现这个功能,它类似于内置的 map() 函数,只不过它是将函数应用于整个表格中的所有元素。

    我们打开文件txt文件③,先观察一下数据:

    $ head Datasets/univerisity_towns.txt
    
    Alabama[edit]
    
    Auburn (Auburn University)[1]
    
    Florence (University of North Alabama)
    
    Jacksonville (Jacksonville State University)[2]
    
    Livingston (University of West Alabama)[2]
    
    Montevallo (University of Montevallo)[2]
    
    Troy (Troy University)[2]
    
    Tuscaloosa (University of Alabama, Stillman College, Shelton State)[3][4]
    
    Tuskegee (Tuskegee University)[5]
    
    Alaska[edit]
    

    观察发现,数据格式有如下特点:

    州A[edit]
    
    城市A(大学)
    
    城市B(大学)
    
    州B[edit]
    
    城市A(大学)
    
    城市B(大学)
    
    ......
    

    我们可以利用这一数据格式,创建一个(州、市)元组列表,并将该列表转化成一个DataFrame。先创建一个列表,列表中包含州和城市(大学)信息。

    university_towns = []
    
    withopen('D:/code/tushare interpret and tech team/python-data-cleaning-master/Datasets/university_towns.txt')asfile:
    
    forlineinfile:
    
    if'[edit]'inline:# 该行有[edit]
    
    state = line# 将改行信息赋值给“州”,记住这个“州”,直到找到下一个为止
    
    else:
    
    university_towns.append((state, line))# 否则,改行为城市信息,并且它们都属于上面的“州”
    
    university_towns[:5]
    
    Out[44]:
    
    [('Alabama[edit]\n','Auburn (Auburn University)[1]\n'),
    
    ('Alabama[edit]\n','Florence (University of North Alabama)\n'),
    
    ('Alabama[edit]\n','Jacksonville (Jacksonville State University)[2]\n'),
    
    ('Alabama[edit]\n','Livingston (University of West Alabama)[2]\n'),
    
    ('Alabama[edit]\n','Montevallo (University of Montevallo)[2]\n')]
    

    pd.DataFrame() 方法将这个列表转换成一个DataFrame,并将列设置为"State"和"RegionName"。Pandas将接受列表中的每个元素,并将元组左边的值传入"State"列,右边的值传入"RegionName"列。

    towns_df = pd.DataFrame(university_towns, columns=['State','RegionName'])
    
    towns_df.head()
    
    Out[45]:
    
    State                                         RegionName
    
    0Alabama[edit]\n                    Auburn (Auburn University)[1]\n
    
    1Alabama[edit]\n           Florence (UniversityofNorth Alabama)\n
    
    2Alabama[edit]\n  Jacksonville (Jacksonville State University)[2]\n
    
    3Alabama[edit]\n       Livingston (UniversityofWest Alabama)[2]\n
    
    4Alabama[edit]\n         Montevallo (UniversityofMontevallo)[2]\n
    

    接下来就要对列中的字符串进行整理,"State"列中的有效信息是州名,"RegionName"列中的有效信息是城市名,其他的字符都可以删掉。当然,除了用之前提到的利用循环和 .str() 方法相结合的方式进行操作,我们还可以选择用 applymap() 方法,它会将传入的函数作用于整个DataFrame所有行列中的每个元素。

    先定义函数 get_citystate(item) ,功能是只提取元素中的有效信息。

    defget_citystate(item):
    
    if' ('initem:
    
    returnitem[:item.find(' (')]
    
    elif'['initem:
    
    returnitem[:item.find('[')]
    
    else:
    
    returnitem
    

    然后,我们将这个函数传入 applymap() ,并应用于towns_df,结果如下:

    towns_df = towns_df.applymap(get_citystate)
    
    towns_df.head()
    
    Out[48]:
    
    State    RegionName
    
    0  Alabama        Auburn
    
    1  Alabama      Florence
    
    2  Alabama  Jacksonville
    
    3  Alabama    Livingston
    
    4  Alabama    Montevallo
    

    现在towns_df表格看起来是不是干净多了!

    06

    删除重复数据

    重复数据会消耗不必要的内存,在处理数据时执行不必要的计算,还会使分析结果出现偏差。因此,我们有必要学习如何删除重复数据。

    先看一个来自DataCamp的数据集,调用info()方法打印出每列数据的具体信息和内存信息,共有24092行数据,内存占用量是753.0+ KB。

    tracks = billboard[['year','artist','track','time']]
    
    print(tracks.info())
    
    RangeIndex:24092entries,0to24091
    
    Data columns (total4columns):
    
    year24092non-nullint64
    
    artist24092non-nullobject
    
    track24092non-nullobject
    
    time24092non-nullobject
    
    dtypes: int64(1),object(3)
    
    memory usage:753.0+ KB
    
    None
    

    下面调用 .drop_duplicates() 函数删除重复数据。

    In [11]: tracks_no_duplicates = tracks.drop_duplicates()
    
    ... print(tracks_no_duplicates.info())
    
    ...
    
    Int64Index:317entries,0to316
    
    Data columns (total4columns):
    
    year317non-nullint64
    
    artist317non-nullobject
    
    track317non-nullobject
    
    time317non-nullobject
    
    dtypes: int64(1),object(3)
    
    memory usage:12.4+ KB
    
    None
    

    删完之后我们发现,数据量减少到了317个,内存占用缩减至12.4+ KB。

    07

    填充缺失值

    数据集中经常会存在缺失值,学会正确处理它们很重要,因为在计算的时候,有些无法处理缺失值,有些则在默认情况下跳过缺失值。而且,了解缺失的数据,并思考用什么值来填充它们,对做出无偏的数据分析至关重要。

    同样是来自DataCamp的一个存在缺失值的数据集:

    In[3]:airquality.head(10)
    
    Out[3]:
    
    OzoneSolar.RWindTempMonthDay
    
    0   41.0190.07.467      5    1
    
    1   36.0118.08.072      5    2
    
    2   12.0149.012.674      5    3
    
    3   18.0313.011.562      5    4
    
    4NaNNaN14.356      5    5
    
    5   28.0NaN14.966      5    6
    
    6   23.0299.08.665      5    7
    
    7   19.099.013.859      5    8
    
    8    8.019.020.161      5    9
    
    9NaN194.08.669      5   10
    

    以"Ozone"列为例,我们可以调用 fillna() 函数,用该列的均值 .mean() 填充NaN值。

    oz_mean = airquality.Ozone.mean()
    
    airquality['Ozone'] = airquality['Ozone'].fillna(oz_mean)
    
    print(airquality.head(10))
    
    Ozone  Solar.R  Wind  Temp  Month  Day
    
    041.000000190.07.46751
    
    136.000000118.08.07252
    
    212.000000149.012.67453
    
    318.000000313.011.56254
    
    443.195402NaN14.35655
    
    528.000000NaN14.96656
    
    623.000000299.08.66557
    
    719.00000099.013.85958
    
    88.00000019.020.16159
    
    943.195402194.08.669510
    

    三、总结

    了解如何进行数据清洗非常重要,因为它是数据科学的重要组成部分。好在Python提供了非常好用的 PandasNumPy 库来帮助我们清理数据集,本文介绍的方法都是在实际中经常会用到的,希望大家能牢记于心。

    如果你对Python编程感兴趣,那么记得来小编的Python学习扣群:1017759557,这里有资源共享,技术解答,大家可以在一起交流Python编程经验,还有小编整理的一份Python学习教程,希望能帮助大家更好的学习python。

    相关文章

      网友评论

        本文标题:Python数据清洗80%的工作量,看这篇就够了

        本文链接:https://www.haomeiwen.com/subject/zgrhtctx.html