Python数据分析实战二:数据分析的准备工作

在第一节中,介绍了pandas基础,给了几个用pandas加载和查看数据的例子。

https://juejin.cn/post/7260893255189053498

但在进行真正的数据分析之前,你就会发现其实收集来的数据很多时候并不能直接拿来使用,会出现空值,异常数据和多份数据源存在大小写不一致等问题。因此还需要做一些准备工作,将数据进行预处理,对收集来的数据做一个清洗和整合,本文主要介绍数据清理和整合的内容。

3.数据清洗方法

3.1 数据去重

使用drop_duplicates()方法可以给数据集去重。该方法可以接受一个或多个列名作为参数,并指定是否保留重复行。
可选参数:
subset: 要去重的列的集合
keep: 保留重复项的规则,是保留第一个还是最后一个
ignore_index:是否重新构建索引

# 创建一个包含重复数据的数据集  
>>> data = pd.DataFrame({  
    'Name': ['Alice', 'Bob', 'Charlie', 'Bob', 'David', 'Alice'],  
    'Age': [25, 30, 35, 30, 40, 45],  
    'Country': ['USA', 'Canada', 'USA', 'Canada', 'USA', 'Australia']  
})  
# 原始数据,其中名为Bob为完全重复数据,名为Alice的为部分重复数据
>>> data
      Name  Age    Country
0    Alice   25        USA
1      Bob   30     Canada
2  Charlie   35        USA
3      Bob   30     Canada
4    David   40        USA
5    Alice   45  Australia

# 删除完全重复的值
>>> data.drop_duplicates()
      Name  Age    Country
0    Alice   25        USA
1      Bob   30     Canada
2  Charlie   35        USA
4    David   40        USA
5    Alice   45  Australia

# 删除特定列重复的值,可以看到默认保留了第一条记录
>>> data.drop_duplicates(subset=['Name'])
      Name  Age Country
0    Alice   25     USA
1      Bob   30  Canada
2  Charlie   35     USA
4    David   40     USA

# 如果想保留最后一条记录,可以将keep参数指定为last
>>> data.drop_duplicates(subset=['Name'], keep='last')
      Name  Age    Country
2  Charlie   35        USA
3      Bob   30     Canada
4    David   40        USA
5    Alice   45  Australia

# 删除重复数据后希望索引依然保持有序,可以用ignore_index=True
>>> data.drop_duplicates(subset=['Name'], keep='last', ignore_index=True)
      Name  Age    Country
0  Charlie   35        USA
1      Bob   30     Canada
2    David   40        USA
3    Alice   45  Australia

3.2 空值处理

3.2.1 如何判断空值

pandas提供了isna,isnull,notna,notnull等空值判断的函数,实际上isna和isnull,notna和notnull是等价的,可以看到它们分别指向同一个地址。

>>> pd.isna
<function isna at 0x00000269EA52C840>
>>> pd.isnull
<function isna at 0x00000269EA52C840>
>>> pd.notna
<function notna at 0x00000269EA53D7B8>
>>> pd.notnull 
<function notna at 0x00000269EA53D7B8>

在用法上以上两个函数返回的是boolean类型的数组。

>>> df1 = pd.DataFrame({'a': ['1', None],'b': ['', 'c'], 'c': [None, None]})
>>> df1.isna()
       a      b     c
0  False  False  True
1   True  False  True
>>> df1.isnull()
       a      b     c
0  False  False  True
1   True  False  True

另外如果要判断DataFrame是否为空,则可以用empty属性:

>>> df1.empty 
False
>>> df2 = pd.DataFrame() # 创建一个空的DataFrame
>>> df2.empty 
True

3.2.2 空值填充

空值填充分为,用指定值替换、前向填充、后向填充、平均值填充、中位数填充几种形式,值得注意的是,inplace参数为True时,空值填充直接在原数据集下生效,反之则会生成新的数据集。默认情况下,inplace参数为False。

# 创建一个包含空值的数据集  
>>> data = pd.DataFrame({'A': [1, 2, None, 4], 'B': [5, None, 7, 8]})  
# 使用fillna() 方法用指定值填充
>>> data0 = data.fillna(0)
>>> data0
     A    B
0  1.0  5.0
1  2.0  0.0
2  0.0  7.0
3  4.0  8.0

# 使用fillna() 方法将空值向前填充
>>> data1 = data.fillna(method='backfill', limit=1)  
>>> data1
     A    B
0  1.0  5.0
1  2.0  7.0
2  4.0  7.0
3  4.0  8.0

# 使用 fillna() 方法将空值向后填充  
>>> data2 = data.fillna(method='backfill', limit=1)  
>>> data2
     A    B
0  1.0  5.0
1  2.0  7.0
2  4.0  7.0
3  4.0  8.0

# 使用 fillna() 方法将空值用平均值填充  
>>> data3 = data.fillna(data.mean())  
>>> data3
          A         B
0  1.000000  5.000000
1  2.000000  6.666667
2  2.333333  7.000000
3  4.000000  8.000000

# 使用 fillna() 方法将空值用中位数填充  
>>> data4 = data.fillna(data.median())  
>>> data4
     A    B
0  1.0  5.0
1  2.0  7.0
2  2.0  7.0
3  4.0  8.0

# 当inplace=True时,直接在原数据集上完成空值替换
>>> data.fillna(0, inplace=True)
>>> data
     A    B
0  1.0  5.0
1  2.0  0.0
2  0.0  7.0
3  4.0  8.0

3.2.3 删除空值

dropna可以删除数据集的空值,还可以用subset指定要删除的是哪几列的空值。

>>> data = pd.DataFrame({'A': [1, 2, None, 4], 'B': [5, None, 7, 8]})
>>> data
     A    B
0  1.0  5.0
1  2.0  NaN
2  NaN  7.0
3  4.0  8.0
# 删除所有含有空值的行
>>> data.dropna()
     A    B
0  1.0  5.0
3  4.0  8.0
# 删除'A'列中所有含有空值的行
data.dropna(subset=['A'])
     A    B
0  1.0  5.0
1  2.0  NaN
3  4.0  8.0
# subset可以指定多个列,删除'A','B'列中所有含有空值的行
data.dropna(subset=['A', 'B'])
     A    B
0  1.0  5.0
3  4.0  8.0

3.3 格式转换

一个典型的例子是当一个DataFrame的类型字符型的0-9,为了满足某些运算,必须先将其转换成整形,用astype()方法可以实现这个功能。

>>> data = pd.DataFrame({'A':['1', '2', '3'], 'B':['4', '5', '6']})
>>> data['A']
0    1
1    2
2    3
Name: A, dtype: object
>>> data['A'].astype(int)
0    1
1    2
2    3
Name: A, dtype: int32

更一般地,用apply函数也可以进行格式转换:

>>> data.apply(lambda x: float(x['A']), axis=1)
0    1.0
1    2.0
2    3.0
dtype: float64

4.数据整合

4.1 列整合

4.1.1 重命名列

rename方法可以给DataFrame的列重命名。

# 基本语法:
# df.rename(columns={'旧列名1': '新列名1', '旧列名2': '新列名2'}, inplace=True)
>>> data = pd.DataFrame({'A':['1', '2', '3'], 'B':['4', '5', '6']})
>>> data.rename(columns={'A':'C', 'B':'D'}, inplace=True)
>>> data
   C  D
0  1  4
1  2  5
2  3  6

4.1.2 删除列

drop方法可以删除某些不需要的列,减少数据集的大小。

>>> df  = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
>>> df.drop(axis=1, columns=['B'], inplace=True)
   A
0  1
1  2
2  3

4.1.3 重新生成索引

使用reset_index方法可以来重新生成索引。通过在DataFrame上调用该方法,原先的索引将会被转化为一列数据,并生成一个新的自然数索引。

>>> data = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['a', 'b', 'c'])
>>> data
   A  B
a  1  4
b  2  5
c  3  6
>>> data.reset_index()
  index  A  B
0     a  1  4
1     b  2  5
2     c  3  6

#如果不想保留index这一列索引,则可以将原有的索引删除
>>> data.reset_index(drop=True)
   A  B
0  1  4
1  2  5
2  3  6

4.2 数据筛选

在一个数据集中,筛选出满足某些条件的数据,是一个比较常见的场景,数据筛选的写法也很多,以下逐一介绍。

  • query方法实现
# 给定一个数据集,下面的用例中亦采用相同数据集
>>> data = pd.DataFrame({  
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],  
    'Age': [25, 30, 35, 40, 45],  
    'Country': ['USA', 'Canada', 'USA', 'USA', 'Australia']  
   })  
>>> data
      Name  Age    Country
0    Alice   25        USA
1      Bob   30     Canada
2  Charlie   35        USA
3    David   40        USA
4      Eve   45  Australia
>>> data.query('Age > 30 and Country == "USA"')
      Name  Age Country
2  Charlie   35     USA
3    David   40     USA
  • loc或者iloc方法实现
# 用loc()方法实现
>>> condition = (data['Age'] > 30) & (data['Country'] == "USA")
>>> data.loc[condition]
      Name  Age Country
2  Charlie   35     USA
3    David   40     USA

# 用iloc()方法实现
>>> condition = (data.iloc[:, 1] > 30) & (data.iloc[:, 2] == 'USA')
>>> data.iloc[:, :][condition]
      Name  Age Country
2  Charlie   35     USA
3    David   40     USA
  • 直接用逻辑运算符生成bool数组实现(同loc方法)
>>> data[(data['Age'] > 30) & (data['Country'] == "USA")]
      Name  Age Country
2  Charlie   35     USA
3    David   40     USA

4.3 归并数据集

concat方法可以将两个数据集合并成一个。

这里讨论的场景是两个列名和数据类型一致的数据集如何归并成一个,如果列名和数据类型不一致,可以参考前面的介绍,对列名和数据类型做相应调整。另外值得说明的是,当列名不一致时,两个数据集可以通过merge()等方法合并成一个数据集,在后续的内容中会继续展开。

>>> data1 = pd.DataFrame({'A': [1, 2], 'B': ['a', 'b']})
>>> data2 = pd.DataFrame({'A': [3, 4], 'C': ['c', 'd']})
# 当列不一致时,归并数据集会生成新的列,并没有达到归并的目的
>>> pd.concat([data1, data2])
   A    B    C
0  1    a  NaN
1  2    b  NaN
0  3  NaN    c
1  4  NaN    d

# 调整data2的数据
>>> data2 = pd.DataFrame({'A': [3, 4], 'B': ['c', 'd']})
>>> pd.concat([data1, data2])
   A  B
0  1  a
1  2  b
0  3  c
1  4  d
# concat完会将保留原来的索引,为了重新生成索引,可以用ignore_index参数。
>>> pd.concat([data1, data2], ignore_index=True)
   A  B
0  1  a
1  2  b
2  3  c
3  4  d
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值