数据分析工具Pandas(7):数据清洗、合并、转化和重构

简介: 数据分析工具Pandas(7):数据清洗、合并、转化和重构

数据分析工具Pandas(1):Pandas的数据结构


数据分析工具Pandas(2):Pandas的索引操作


数据分析工具Pandas(3):Pandas的对齐运算


数据分析工具Pandas(4):Pandas的函数应用


数据分析工具Pandas(5):Pandas的层级索引


数据分析工具Pandas(6):Pandas统计计算和描述


数据清洗

数据清洗是数据分析关键的一步,直接影响之后的处理工作


数据需要修改吗?有什么需要修改的吗?数据应该怎么调整才能适用于接下来的分析和挖掘?


是一个迭代的过程,实际项目中可能需要不止一次地执行这些清洗操作


处理缺失数据:pd.fillna(),pd.dropna()


数据连接(pd.merge)

pd.merge


根据单个或多个键将不同DataFrame的行连接起来


类似数据库的连接操作

import pandas as pd
import numpy as np
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                        'data1' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],
                        'data2' : np.random.randint(0,10,3)})
print(df_obj1)
print(df_obj2)

运行结果:

   data1 key
   data1 key
0      8   b
1      8   b
2      3   a
3      5   c
4      4   a
5      9   a
6      6   b
   data2 key
0      9   a
1      0   b
2      3   d

1. 默认将重叠列的列名作为“外键”进行连接

# 默认将重叠列的列名作为“外键”进行连接
print(pd.merge(df_obj1, df_obj2))

运行结果:

   data1 key  data2
0      8   b      0
1      8   b      0
2      6   b      0
3      3   a      9
4      4   a      9
5      9   a      9

2. on显示指定“外键”

# on显示指定“外键”
print(pd.merge(df_obj1, df_obj2, on='key'))

运行结果:

   data1 key  data2
0      8   b      0
1      8   b      0
2      6   b      0
3      3   a      9
4      4   a      9
5      9   a      9

3. left_on,左侧数据的“外键”,right_on,右侧数据的“外键”

# left_on,right_on分别指定左侧数据和右侧数据的“外键”
# 更改列名
df_obj1 = df_obj1.rename(columns={'key':'key1'})
df_obj2 = df_obj2.rename(columns={'key':'key2'})
print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2'))

运行结果:

   data1 key1  data2 key2
0      8    b      0    b
1      8    b      0    b
2      6    b      0    b
3      3    a      9    a
4      4    a      9    a
5      9    a      9    a
默认是“内连接”(inner),即结果中的键是交集
how指定连接方式
4. “外连接”(outer),结果中的键是并集

默认是“内连接”(inner),即结果中的键是交集

how指定连接方式

4. “外连接”(outer),结果中的键是并集

# “外连接”
print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='outer'))

运行结果:

   data1 key1  data2 key2
0    8.0    b    0.0    b
1    8.0    b    0.0    b
2    6.0    b    0.0    b
3    3.0    a    9.0    a
4    4.0    a    9.0    a
5    9.0    a    9.0    a
6    5.0    c    NaN  NaN
7    NaN  NaN    3.0    d

5. “左连接”(left)

# 左连接
print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='left'))

运行结果:

   data1 key1  data2 key2
0      8    b    0.0    b
1      8    b    0.0    b
2      3    a    9.0    a
3      5    c    NaN  NaN
4      4    a    9.0    a
5      9    a    9.0    a
6      6    b    0.0    b

6. “右连接”(right)

# 右连接
print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='right'))

运行结果:

   data1 key1  data2 key2
0    8.0    b      0    b
1    8.0    b      0    b
2    6.0    b      0    b
3    3.0    a      9    a
4    4.0    a      9    a
5    9.0    a      9    a
6    NaN  NaN      3    d 

7. 处理重复列名

suffixes,默认为_x, _y

# 处理重复列名
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                        'data' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],
                        'data' : np.random.randint(0,10,3)})
print(pd.merge(df_obj1, df_obj2, on='key', suffixes=('_left', '_right')))

运行结果:

   data_left key  data_right
0          9   b           1
1          5   b           1
2          1   b           1
3          2   a           8
4          2   a           8
5          5   a           8

8. 按索引连接

left_index=True或right_index=True

# 按索引连接
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                        'data1' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'data2' : np.random.randint(0,10,3)}, index=['a', 'b', 'd'])
print(pd.merge(df_obj1, df_obj2, left_on='key', right_index=True))

运行结果:

   data1 key  data2
0      3   b      6
1      4   b      6
6      8   b      6
2      6   a      0
4      3   a      0
5      0   a      0

数据合并(pd.concat)

  • 沿轴方向将多个对象合并到一起

1. NumPy的concat

np.concatenate

import numpy as np
import pandas as pd
arr1 = np.random.randint(0, 10, (3, 4))
arr2 = np.random.randint(0, 10, (3, 4))
print(arr1)
print(arr2)
print(np.concatenate([arr1, arr2]))
print(np.concatenate([arr1, arr2], axis=1))

运行结果:

# print(arr1)
[[3 3 0 8]
 [2 0 3 1]
 [4 8 8 2]]
# print(arr2)
[[6 8 7 3]
 [1 6 8 7]
 [1 4 7 1]]
# print(np.concatenate([arr1, arr2]))
 [[3 3 0 8]
 [2 0 3 1]
 [4 8 8 2]
 [6 8 7 3]
 [1 6 8 7]
 [1 4 7 1]]
# print(np.concatenate([arr1, arr2], axis=1)) 
[[3 3 0 8 6 8 7 3]
 [2 0 3 1 1 6 8 7]
 [4 8 8 2 1 4 7 1]]

2. pd.concat

  • 注意指定轴方向,默认axis=0
  • join指定合并方式,默认为outer
  • Series合并时查看行索引有无重复

1) index 没有重复的情况

# index 没有重复的情况
ser_obj1 = pd.Series(np.random.randint(0, 10, 5), index=range(0,5))
ser_obj2 = pd.Series(np.random.randint(0, 10, 4), index=range(5,9))
ser_obj3 = pd.Series(np.random.randint(0, 10, 3), index=range(9,12))
print(ser_obj1)
print(ser_obj2)
print(ser_obj3)
print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))
print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1))

运行结果:

# print(ser_obj1)
0    1
1    8
2    4
3    9
4    4
dtype: int64
# print(ser_obj2)
5    2
6    6
7    4
8    2
dtype: int64
# print(ser_obj3)
9     6
10    2
11    7
dtype: int64
# print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))
0     1
1     8
2     4
3     9
4     4
5     2
6     6
7     4
8     2
9     6
10    2
11    7
dtype: int64
# print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1))
      0    1    2
0   1.0  NaN  NaN
1   5.0  NaN  NaN
2   3.0  NaN  NaN
3   2.0  NaN  NaN
4   4.0  NaN  NaN
5   NaN  9.0  NaN
6   NaN  8.0  NaN
7   NaN  3.0  NaN
8   NaN  6.0  NaN
9   NaN  NaN  2.0
10  NaN  NaN  3.0
11  NaN  NaN  3.0

2) index 有重复的情况

# index 有重复的情况
ser_obj1 = pd.Series(np.random.randint(0, 10, 5), index=range(5))
ser_obj2 = pd.Series(np.random.randint(0, 10, 4), index=range(4))
ser_obj3 = pd.Series(np.random.randint(0, 10, 3), index=range(3))
print(ser_obj1)
print(ser_obj2)
print(ser_obj3)
print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))

运行结果:

# print(ser_obj1)
0    0
1    3
2    7
3    2
4    5
dtype: int64
# print(ser_obj2)
0    5
1    1
2    9
3    9
dtype: int64
# print(ser_obj3)
0    8
1    7
2    9
dtype: int64
# print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))
0    0
1    3
2    7
3    2
4    5
0    5
1    1
2    9
3    9
0    8
1    7
2    9
dtype: int64
# print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1, join='inner')) 
# join='inner' 将去除NaN所在的行或列
   0  1  2
0  0  5  8
1  3  1  7
2  7  9  9

3) DataFrame合并时同时查看行索引和列索引有无重复

 

df_obj1 = pd.DataFrame(np.random.randint(0, 10, (3, 2)), index=['a', 'b', 'c'],
                       columns=['A', 'B'])
df_obj2 = pd.DataFrame(np.random.randint(0, 10, (2, 2)), index=['a', 'b'],
                       columns=['C', 'D'])
print(df_obj1)
print(df_obj2)
print(pd.concat([df_obj1, df_obj2]))
print(pd.concat([df_obj1, df_obj2], axis=1, join='inner'))

运行结果:

# print(df_obj1)
   A  B
a  3  3
b  5  4
c  8  6
# print(df_obj2)
   C  D
a  1  9
b  6  8
# print(pd.concat([df_obj1, df_obj2]))
     A    B    C    D
a  3.0  3.0  NaN  NaN
b  5.0  4.0  NaN  NaN
c  8.0  6.0  NaN  NaN
a  NaN  NaN  1.0  9.0
b  NaN  NaN  6.0  8.0
# print(pd.concat([df_obj1, df_obj2], axis=1, join='inner'))
   A  B  C  D
a  3  3  1  9
b  5  4  6  8

数据重构

1. stack

  • 将列索引旋转为行索引,完成层级索引
  • DataFrame->Series
import numpy as np
import pandas as pd
df_obj = pd.DataFrame(np.random.randint(0,10, (5,2)), columns=['data1', 'data2'])
print(df_obj)
stacked = df_obj.stack()
print(stacked)

运行结果:

# print(df_obj)
   data1  data2
0      7      9
1      7      8
2      8      9
3      4      1
4      1      2
# print(stacked)
0  data1    7
   data2    9
1  data1    7
   data2    8
2  data1    8
   data2    9
3  data1    4
   data2    1
4  data1    1
   data2    2
dtype: int64

2. unstack

  • 将层级索引展开
  • Series->DataFrame
  • 认操作内层索引,即level=-1
# 默认操作内层索引
print(stacked.unstack())
# 通过level指定操作索引的级别
print(stacked.unstack(level=0))

运行结果:

# print(stacked.unstack())
   data1  data2
0      7      9
1      7      8
2      8      9
3      4      1
4      1      2
# print(stacked.unstack(level=0))
       0  1  2  3  4
data1  7  7  8  4  1
data2  9  8  9  1  2

数据转换

一、 处理重复数据

1 duplicated() 返回布尔型Series表示每行是否为重复行

import numpy as np
import pandas as pd
df_obj = pd.DataFrame({'data1' : ['a'] * 4 + ['b'] * 4,
                       'data2' : np.random.randint(0, 4, 8)})
print(df_obj)
print(df_obj.duplicated())

运行结果:

# print(df_obj)
  data1  data2
0     a      3
1     a      2
2     a      3
3     a      3
4     b      1
5     b      0
6     b      3
7     b      0
# print(df_obj.duplicated())
0    False
1    False
2     True
3     True
4    False
5    False
6    False
7     True
dtype: bool

2 drop_duplicates() 过滤重复行

默认判断全部列

可指定按某些列判断

print(df_obj.drop_duplicates())
print(df_obj.drop_duplicates('data2'))

运行结果:

# print(df_obj.drop_duplicates())
  data1  data2
0     a      3
1     a      2
4     b      1
5     b      0
6     b      3
# print(df_obj.drop_duplicates('data2'))
  data1  data2
0     a      3
1     a      2
4     b      1
5     b      0# print(df_obj.drop_duplicates())
  data1  data2
0     a      3
1     a      2
4     b      1
5     b      0
6     b      3
# print(df_obj.drop_duplicates('data2'))
  data1  data2
0     a      3
1     a      2
4     b      1
5     b      0

3. 根据map传入的函数对每行或每列进行转换

  • Series根据map传入的函数对每行或每列进行转换

示例代码:

ser_obj = pd.Series(np.random.randint(0,10,10))
print(ser_obj)
print(ser_obj.map(lambda x : x ** 2))

运行结果:

# print(ser_obj)
0    1
1    4
2    8
3    6
4    8
5    6
6    6
7    4
8    7
9    3
dtype: int64
# print(ser_obj.map(lambda x : x ** 2))
0     1
1    16
2    64
3    36
4    64
5    36
6    36
7    16
8    49
9     9
dtype: int64


目录
相关文章
|
12月前
|
自然语言处理 数据挖掘 数据处理
告别低效代码:用对这10个Pandas方法让数据分析效率翻倍
本文将介绍 10 个在数据处理中至关重要的 Pandas 技术模式。这些模式能够显著减少调试时间,提升代码的可维护性,并构建更加清晰的数据处理流水线。
369 3
告别低效代码:用对这10个Pandas方法让数据分析效率翻倍
|
SQL 分布式计算 数据挖掘
从Excel到高级工具:数据分析进阶指南
从Excel到高级工具:数据分析进阶指南
607 54
|
数据采集 数据可视化 数据挖掘
Pandas数据应用:天气数据分析
本文介绍如何使用 Pandas 进行天气数据分析。Pandas 是一个强大的 Python 数据处理库,适合处理表格型数据。文章涵盖加载天气数据、处理缺失值、转换数据类型、时间序列分析(如滚动平均和重采样)等内容,并解决常见报错如 SettingWithCopyWarning、KeyError 和 TypeError。通过这些方法,帮助用户更好地进行气候趋势预测和决策。
532 71
|
数据采集 数据挖掘 数据处理
如何使用 Pandas 库进行数据清洗和预处理?
数据清洗和预处理是数据分析中至关重要的步骤,Pandas库提供了丰富的函数和方法来完成这些任务
1033 64
|
数据挖掘 关系型数据库 Serverless
利用数据分析工具评估特定业务场景下扩缩容操作对性能的影响
通过以上数据分析工具的运用,可以深入挖掘数据背后的信息,准确评估特定业务场景下扩缩容操作对 PolarDB Serverless 性能的影响。同时,这些分析结果还可以为后续的优化和决策提供有力的支持,确保业务系统在不断变化的环境中保持良好的性能表现。
547 154
|
数据采集 分布式计算 大数据
Pandas数据清洗:缺失值处理
本文详细介绍了Pandas库中处理缺失值的方法,包括检测缺失值、删除缺失值、填充缺失值和插值法填充缺失值。通过基础概念和代码示例,帮助读者理解和解决数据清洗中常见的缺失值问题。
1306 80
|
存储 数据采集 数据可视化
Pandas数据应用:电子商务数据分析
本文介绍如何使用 Pandas 进行电子商务数据分析,涵盖数据加载、清洗、预处理、分析与可视化。通过 `read_csv` 等函数加载数据,利用 `info()` 和 `describe()` 探索数据结构和统计信息。针对常见问题如缺失值、重复记录、异常值等,提供解决方案,如 `dropna()`、`drop_duplicates()` 和正则表达式处理。结合 Matplotlib 等库实现数据可视化,探讨内存不足和性能瓶颈的应对方法,并总结常见报错及解决策略,帮助提升电商企业的数据分析能力。
824 73
|
SQL 自然语言处理 数据可视化
📊 Quick BI 真实体验评测:小白也能快速上手的数据分析工具!
作为一名软件开发工程师,我体验了阿里云的Quick BI工具。从申请试用账号到上传数据、创建数据集,再到搭建仪表板和使用智能小Q功能,整个过程流畅且简单易用。尤其对非专业数据分析人士来说,拖拽式设计和自然语言问数功能极大降低了操作门槛。虽然在试用入口明显度和复杂语义理解上还有提升空间,但整体体验令人满意。Quick BI让我改变了对数据分析的认知,值得推荐给需要快速制作报表的团队成员。
|
人工智能 数据可视化 前端开发
Probly:开源 AI Excel表格工具,交互式生成数据分析结果与可视化图表
Probly 是一款结合电子表格功能与 Python 数据分析能力的 AI 工具,支持在浏览器中运行 Python 代码,提供交互式电子表格、数据可视化和智能分析建议,适合需要强大数据分析功能又希望操作简便的用户。
1871 2
|
SQL 供应链 数据可视化
这可能是最适合探索式数据分析的工具
SPL(Structured Process Language)是一款结合了强大计算能力和灵活交互性的数据分析工具,特别适合探索式数据分析。它不仅支持分步执行和实时查看每步结果,还提供了丰富的表格数据计算类库,简化复杂运算。与Excel相比,SPL在处理复杂逻辑时更加简洁高效;相较于SQL和Python,SPL具备更好的交互性和更直观的操作体验。通过SPL的XLL插件,用户可以在Excel环境中直接使用SPL的强大功能,充分发挥两者优势。SPL开源免费,是探索式数据分析的理想选择。

热门文章

最新文章