zoukankan      html  css  js  c++  java
  • 用pandas进行数据清洗(二)(Data Analysis Pandas Data Munging/Wrangling)

    在《用pandas进行数据清洗(一)(Data Analysis Pandas Data Munging/Wrangling)》中,我们介绍了数据清洗经常用到的一些pandas命令。

    接下来看看这份数据的具体清洗步骤:

       Transaction_ID Transaction_Date Product_ID Quantity Unit_Price Total_Price
    0               1       2010-08-21          2        1         30          30
    1               2       2011-05-26          4        1         40          40
    2               3       2011-06-16          3      NaN         32          32
    3               4       2012-08-26          2        3         55         165
    4               5       2013-06-06          4        1        124         124
    5               1       2010-08-21          2        1         30          30
    6               7       2013-12-30                                           
    7               8       2014-04-24          2        2        NaN         NaN
    8               9       2015-04-24          4        3         60        1800
    9              10       2016-05-08          4        4          9          36

    1,查看数据的行列数:

    print(transactions.shape)
    (10, 6)

    数据一共有10行6列。

    2,查看数据的数据类型:

    print(transactions.dtypes)
    Transaction_ID               int64
    Transaction_Date    datetime64[ns]
    Product_ID                  object
    Quantity                    object
    Unit_Price                  object
    Total_Price                 object

    Transaction_ID列是整数,Transaction_Date列是时间序列,其余几列都是object。

    3,以上两步也可以用info()命令替代:

    RangeIndex: 10 entries, 0 to 9
    Data columns (total 6 columns):
    Transaction_ID      10 non-null int64
    Transaction_Date    10 non-null datetime64[ns]
    Product_ID          10 non-null object
    Quantity            9 non-null object
    Unit_Price          9 non-null object
    Total_Price         9 non-null object
    dtypes: datetime64[ns](1), int64(1), object(4)
    memory usage: 560.0+ bytes
    None

    RangeIndex: 10 entries 表示一共有10行记录,Data columns (total 6 columns) 表示一共有6列,接下去显示的是每列非空数值的个数以及类型。

    4,查看是哪几行,哪几列有缺失值,以及一共有多少行多少列有缺失值:

    print("哪几行有缺失值:")
    print(transactions.apply(lambda x: sum(x.isnull()),axis=1))
    哪几行有缺失值:
    0    0
    1    0
    2    1
    3    0
    4    0
    5    0
    6    0
    7    2
    8    0
    9    0
    print("哪几列有缺失值:")
    print(transactions.apply(lambda x: sum(x.isnull()),axis=0))
    哪几列有缺失值:
    Transaction_ID      0
    Transaction_Date    0
    Product_ID          0
    Quantity            1
    Unit_Price          1
    Total_Price         1
    print("一共有多少行有缺失值:")
    print(len(transactions.apply(lambda x: sum(x.isnull()),axis=1).nonzero()[0]))
    一共有多少行有缺失值:
    2
    print("一共有多少列有缺失值:")
    print(len(transactions.apply(lambda x: sum(x.isnull()),axis=0).nonzero()[0]))
    一共有多少列有缺失值:
    3

    需要注意的是,此数据集中有一些有空格的地方,也应视为缺失值,因此需要把空格处转换为NaN显示:

    transactions=transactions.applymap(lambda x: np.NaN if str(x).isspace() else x)

    现在数据集显示如下:

       Transaction_ID Transaction_Date  Product_ID  Quantity  Unit_Price  
    0               1       2010-08-21         2.0       1.0        30.0   
    1               2       2011-05-26         4.0       1.0        40.0   
    2               3       2011-06-16         3.0       NaN        32.0   
    3               4       2012-08-26         2.0       3.0        55.0   
    4               5       2013-06-06         4.0       1.0       124.0   
    5               1       2010-08-21         2.0       1.0        30.0   
    6               7       2013-12-30         NaN       NaN         NaN   
    7               8       2014-04-24         2.0       2.0         NaN   
    8               9       2015-04-24         4.0       3.0        60.0   
    9              10       2016-05-08         4.0       4.0         9.0   
    
       Total_Price  
    0         30.0  
    1         40.0  
    2         32.0  
    3        165.0  
    4        124.0  
    5         30.0  
    6          NaN  
    7          NaN  
    8       1800.0  
    9         36.0  

    5,去除缺失值:

    transactions.dropna(inplace=True)

    6,当然,我们也可以选择不去除缺失值,而是进行填充,这种方法适用于数据量少的情况下,这里选择向后填充:

    transactions.fillna(method='backfill',inplace=True)

    现在数据集如下:

       Transaction_ID Transaction_Date  Product_ID  Quantity  Unit_Price  
    0               1       2010-08-21         2.0       1.0        30.0   
    1               2       2011-05-26         4.0       1.0        40.0   
    2               3       2011-06-16         3.0       3.0        32.0   
    3               4       2012-08-26         2.0       3.0        55.0   
    4               5       2013-06-06         4.0       1.0       124.0   
    5               1       2010-08-21         2.0       1.0        30.0   
    6               7       2013-12-30         2.0       2.0        60.0   
    7               8       2014-04-24         2.0       2.0        60.0   
    8               9       2015-04-24         4.0       3.0        60.0   
    9              10       2016-05-08         4.0       4.0         9.0   
    
       Total_Price  
    0         30.0  
    1         40.0  
    2         32.0  
    3        165.0  
    4        124.0  
    5         30.0  
    6       1800.0  
    7       1800.0  
    8       1800.0  
    9         36.0

    7,现在来试一下用均值填充:

    transactions.fillna(transactions.mean(),inplace=True)

    现在数据集如下:

       Transaction_ID Transaction_Date  Product_ID  Quantity  Unit_Price  
    0               1       2010-08-21         2.0       1.0        30.0   
    1               2       2011-05-26         4.0       1.0        40.0   
    2               3       2011-06-16         3.0       2.0        32.0   
    3               4       2012-08-26         2.0       3.0        55.0   
    4               5       2013-06-06         4.0       1.0       124.0   
    5               1       2010-08-21         2.0       1.0        30.0   
    6               7       2013-12-30         3.0       2.0        47.5   
    7               8       2014-04-24         2.0       2.0        47.5   
    8               9       2015-04-24         4.0       3.0        60.0   
    9              10       2016-05-08         4.0       4.0         9.0   
    
       Total_Price  
    0       30.000  
    1       40.000  
    2       32.000  
    3      165.000  
    4      124.000  
    5       30.000  
    6      282.125  
    7      282.125  
    8     1800.000  
    9       36.000  

    *注意:如果数据集里有异常值,应先去除异常值,再用均值填充。

    8,再试一下用插值法进行填充,默认是线性插值法,适用于列数据呈线性关系的时候:

    transactions.interpolate(inplace=True)

    显然这里不符合要求,因此不显示更新的数据集了。仅作演示之用。

    9,显示有重复值的行:

    print(transactions.duplicated())
    0    False
    1    False
    2    False
    3    False
    4    False
    5     True
    6    False
    7    False
    8    False
    9    False

    显示索引为5的这一行有重复值。显示一共有多少行重复值:transactions.duplicated().sum()。

    10,去除重复值:

    transactions.drop_duplicates(inplace=True)

    11,这里选择用均值填充缺失值,现在需要查找异常值,先用describe()方法显示数值型数据的整体情况:

    print(transactions.describe())
           Transaction_ID  Product_ID  Quantity  Unit_Price  Total_Price
    count        9.000000    9.000000  9.000000    9.000000     9.000000
    mean         5.444444    3.111111  2.111111   49.444444   310.138889
    std          3.205897    0.927961  1.054093   31.850672   567.993712
    min          1.000000    2.000000  1.000000    9.000000    30.000000
    25%          3.000000    2.000000  1.000000   32.000000    36.000000
    50%          5.000000    3.000000  2.000000   47.500000   124.000000
    75%          8.000000    4.000000  3.000000   55.000000   282.125000
    max         10.000000    4.000000  4.000000  124.000000  1800.000000

    查看Quantity, Unit_Price,Total_Price的最大最小值后发现,Quantity没什么问题,Unit_Price和Total_Price的最大值有些异常,用最大的Quantity乘以Unit_Price得到的是496,远低于1800,因此确定Total_Price有异常值。而Unit_Price的最大值不能确定有没有问题,在查看数据集后,发现没什么问题,故保留。

    12,用掩码查找异常值,在数据上下限范围之外的数值即为异常值(数据上限通常是Q3+1.5*IQR,数据下限通常是Q1-1.5*IQR):

    IQR=transactions.describe().loc['75%','Total_Price']-transactions.describe().loc['25%','Total_Price']
    upper_extreme=transactions.describe().loc['75%','Total_Price']+1.5*IQR
    lower_extreme=transactions.describe().loc['25%','Total_Price']-1.5*IQR
    print(transactions.loc[((transactions['Total_Price']>upper_extreme) | (transactions['Total_Price']<lower_extreme))])
       Transaction_ID Transaction_Date  Product_ID  Quantity  Unit_Price  
    8               9       2015-04-24         4.0       3.0        60.0   
    
       Total_Price  
    8       1800.0  

    先计算出Total_Price的IQR,据此再计算出它的上下限,查找出有异常值的行。

    13,用箱线图查找异常值:

    import matplotlib.pyplot as plt
    fig,ax=plt.subplots()
    
    ax.boxplot(transactions['Total_Price'])
    plt.shaow()

    显示Total_Price这一列有异常值(圆点)。

    14,处理异常值,查看数据集后发现有异常值这一行是Total_Price多加了一个0,故用180替代1800:

    transactions.replace(1800,180,inplace=True)

    现在数据集如下:

       Transaction_ID Transaction_Date  Product_ID  Quantity  Unit_Price  
    0               1       2010-08-21         2.0       1.0        30.0   
    1               2       2011-05-26         4.0       1.0        40.0   
    2               3       2011-06-16         3.0       2.0        32.0   
    3               4       2012-08-26         2.0       3.0        55.0   
    4               5       2013-06-06         4.0       1.0       124.0   
    6               7       2013-12-30         3.0       2.0        47.5   
    7               8       2014-04-24         2.0       2.0        47.5   
    8               9       2015-04-24         4.0       3.0        60.0   
    9              10       2016-05-08         4.0       4.0         9.0   
    
       Total_Price  
    0       30.000  
    1       40.000  
    2       32.000  
    3      165.000  
    4      124.000  
    6      282.125  
    7      282.125  
    8      180.000  
    9       36.000 

    这个数据集的清洗工作到此为止,因为该数据集非常简单,因此只能用作演示。现实中的数据集要比这个复杂很多,其清洗内容还包括数据类型的转换,数据格式的转换,添加特征等等。

  • 相关阅读:
    MYSQL 字符串操作
    关于IT企业组织架构的一些思考
    关于《Java封面》一些感想
    浏览器缓存资源文件的问题
    为什么《一个程序员怎么能做出这样的事情》?
    TCP/IP协议中的参数说明
    java编译器对代码的优化
    事务属性小结
    事务的编程模型
    从阿里云os和Google之争看开源协议
  • 原文地址:https://www.cnblogs.com/HuZihu/p/11404528.html
Copyright © 2011-2022 走看看