当前位置:首页>python>从零开始学Python数据清洗(二)

从零开始学Python数据清洗(二)

  • 2026-10-11 07:44:02
从零开始学Python数据清洗(二)

Pandas核心数据结构

如果把pandas比作一座房子的骨架,Series是一根根柱子,DataFrame就是由柱子搭建起来的整个房间。理解这两种结构,你就掌握了数据清洗的通用语言。

文中涉及到的数据文件可以联系我发给你,因为我还不知道怎么在公众号插入文件


一、认识pandas

pandas 是Python数据清洗的核心库。它的名字源自"面板数据"(Panel Data),最早由Wes McKinney于2008年创建,如今已成为全球数据科学家日常使用最频繁的Python库之一。

为什么pandas能成为数据清洗的事实标准?

  • • 直观的数据结构:它把表格数据变成了可以直接操作的对象,你不再需要写循环去遍历每一行
  • • 丰富的内置函数:筛选、分组、合并、填充缺失值——几乎所有清洗操作都有现成方法
  • • 与其他工具无缝衔接:可以读取Excel、CSV、SQL,也能直接喂给机器学习库

一句话总结:在Python生态中,pandas之于表格数据,就像Word之于文档——它就是你处理和清洗数据的默认工具。

本系列的所有代码都将围绕pandas展开。让我们从它最基础的两个数据结构开始。


二、Series:一维数据列

Series 是pandas中最基本的数据结构,你可以把它理解成"带标签的一维数组"。Excel表格中的一列,本质上就是一个Series。

创建Series

import pandas as pdimport numpy as np# 从列表创建,默认索引从0开始s1 = pd.Series([22969, 6315, 3222, 4518, 5176])print(s1)

输出:

0    229691     63152     32223     45184     5176dtype: int64

左边那一列数字(0, 1, 2...)就是索引(index),右边是值(values)。索引可以自定义:

# 自定义索引,让每个值拥有一个有意义的标签salary = pd.Series(    [22969, 6315, 3222, 4518, 5176],    index=['EMP0001', 'EMP0002', 'EMP0003', 'EMP0004', 'EMP0005'],    name='薪资')print(salary)
EMP0001    22969EMP0002     6315EMP0003     3222EMP0004     4518EMP0005     5176Name: 薪资, dtype: int64

Series的核心属性

print(salary.values)   # 值: [22969  6315  3222  4518  5176]print(salary.index)    # 索引: Index(['EMP0001', ..., 'EMP0005'])print(salary.dtype)    # 数据类型: int64print(salary.name)     # Series名称: 薪资

Series的基本操作

Series支持类似numpy数组的向量化操作,这是它比Python列表强大得多的地方:

salary * 1.2          # 所有薪资乘以1.2(年终奖系数)salary.mean()         # 求均值salary.max()          # 求最大值salary.describe()     # 一次性获得所有描述性统计

关键理解:Series的运算是对所有元素同时进行的(向量化),不需要写for循环。这既是性能优势,也是代码简洁的根源。


三、DataFrame:二维数据表

DataFrame 是由多个Series按列组合而成的二维表格,是pandas中最核心、最常用的数据结构。你可以把它看作Excel的一个工作表,或者SQL的一张表。

创建DataFrame

方法一:从字典创建(最常用)

df = pd.DataFrame({    '姓名': ['张三', '李四', '王五'],    '年龄': [28, 35, 42],    '部门': ['技术部', '市场部', '运营部'],    '薪资': [12000, 9000, 15000]})print(df)

方法二:从列表嵌套创建

data = [    ['张三', 28, '技术部', 12000],    ['李四', 35, '市场部', 9000],    ['王五', 42, '运营部', 15000]]df = pd.DataFrame(data, columns=['姓名', '年龄', '部门', '薪资'])

方法三:从numpy数组创建

arr = np.array([    [28, 12000],    [35, 9000],    [42, 15000]])df = pd.DataFrame(arr, columns=['年龄', '薪资'])

三种方法殊途同归,选择你最顺手的方式即可。从字典创建是最直观、最推荐的方式。


四、DataFrame的核心属性

拿到一个DataFrame后,第一件事就是了解它的基本信息。以下是每次必须查看的属性:

# 读取真实数据来演示df = pd.read_csv('data_python/employee_data.csv')df.shape       # (500, 8) —— 500行,8列df.columns     # Index(['emp_id', 'name', 'department', ...])df.index       # RangeIndex(start=0, stop=500, step=1)df.dtypes      # 每一列的数据类型df.values      # 底层的numpy数组
属性
返回内容
用途
df.shape
(行数, 列数) 的元组
了解数据规模
df.columns
所有列名的Index对象
查看有哪些字段
df.index
行索引
确认索引范围
df.dtypes
每列的数据类型Series
检查类型是否正确
df.values
底层的numpy二维数组
转换格式时使用

新手提示:shape 和 dtypes 是两个最重要的属性。拿到数据第一步先看 shape 确认数据量,再看 dtypes 确认每列的类型是否和你预期一致。


五、快速浏览数据的三个方法

.head() 和 .tail() — 看头看尾

df.head()     # 默认显示前5行df.head(10)   # 显示前10行df.tail()     # 默认显示后5行df.tail(3)    # 显示最后3行

这两个方法让你快速"瞥一眼"数据长什么样,不需要打印整个表格。

.info() — 数据的体检报告

df.info()

输出示例:

<class 'pandas.core.frame.DataFrame'>RangeIndex: 500 entries, 0 to 499Data columns (total 8 columns): #   Column      Non-Null Count  Dtype---  ------      --------------  ----- 0   emp_id      500 non-null    object 1   name        500 non-null    object 2   department  450 non-null    object 3   gender      500 non-null    object 4   age         495 non-null    float64 5   education   475 non-null    object 6   hire_date   500 non-null    object 7   salary      488 non-null    float64

从 Non-Null Count 这一列,你能立刻发现哪些字段存在缺失值——这是数据清洗的起点。

.describe() — 数值列的统计摘要

df.describe()

输出包括 count(计数)、mean(均值)、std(标准差)、min(最小值)、25%/50%/75%分位数、max(最大值)。

实用技巧:如果 describe() 中某列的min或max数值看起来很不合理(比如年龄出现200),那很可能存在异常值——这是我们后面要重点处理的问题。


六、索引:数据的导航系统

索引是DataFrame的行标签,相当于Excel的行号,但它可以自定义为任何有意义的值。

# 默认索引是 RangeIndex(0, 1, 2, ...)print(df.index)# 将 emp_id 设为索引df2 = df.set_index('emp_id')print(df2.index)# 通过索引取值print(df2.loc['EMP0001'])   # 用loc通过标签取值print(df.iloc[0])           # 用iloc通过位置取值(第0行)

loc 和 iloc 的区别是最基础也最容易混淆的知识点:

方法
索引方式
示例
df.loc[]
按标签(索引名)查找
df.loc['EMP0001']
df.iloc[]
按位置(数字下标)查找
df.iloc[0]
df.loc[:, 'salary']
按标签选列
选取salary列
df.iloc[:, 7]
按位置选列
选取第7列(从0开始)

七、快速查看我们的6套数据

现在,让我们用刚学的函数来浏览本系列的6个练习数据集:

import pandas as pdfrom pathlib import Pathdata_dir = Path('data_python')# 遍历所有数据集,打印基本信息for file in sorted(data_dir.glob('*.csv')):    df = pd.read_csv(file)    print(f"{file.name:30s} | shape: {str(df.shape):12s} | columns: {list(df.columns)}")

输出:

customer_info.csv               | shape: (300, 7)     | columns: ['customer_id', 'full_name', ...]department_data.csv             | shape: (5, 5)       | columns: ['department', 'dept_code', ...]employee_data.csv               | shape: (500, 8)     | columns: ['emp_id', 'name', ...]sales_orders.csv                | shape: (610, 6)     | columns: ['order_id', 'order_date', ...]survey_data.csv                 | shape: (400, 6)     | columns: ['respondent_id', 'age_group', ...]time_series_sales.csv           | shape: (471, 5)     | columns: ['date', 'product_id', ...]

这就是我们用一行代码对6套数据做的"全身扫描"。接下来深入学习每个数据集的细节:

emp = pd.read_csv('data_python/employee_data.csv')sales = pd.read_csv('data_python/sales_orders.csv')cust = pd.read_csv('data_python/customer_info.csv')print("=" * 50)print("员工数据 .info()")emp.info()print("\n" + "=" * 50)print("销售数据 .head(3)")print(sales.head(3))print("\n" + "=" * 50)print("客户数据 .describe()")print(cust.describe())

你会在输出中看到缺失值、奇怪的数据类型(比如日期被识别为object)、以及异常的范围——这些问题为后续的清洗练习做好了铺垫。


小结

今天你掌握了pandas最核心的两个数据结构:

维度
Series
DataFrame
维度
一维(单列)
二维(多行多列)
类比
Excel的一列
Excel的一个工作表
索引
每个元素有一个标签
每行有一个标签
创建
pd.Series([...])pd.DataFrame({...})
查看结构
.shape
, .dtype
.shape
, .dtypes, .columns
快速浏览
.head()
, .describe()
.head()
, .tail(), .info()
取值
s[0]
 或 s['label']
.loc[]
 或 .iloc[]

你现在已经拥有读懂任何pandas代码的基础能力。下一章,我们将进入实战的第一环——把数据读进来。


下一篇预告

下一篇 《数据读取与写入》 将教你如何读取各种格式的数据文件:CSV的编码问题如何解决?Excel工作表如何选择?数据清洗完成后如何保存?还有中文字符乱码的终极解决方案。打好地基,准备动手!


#Pandas #DataFrame #Series #Python数据结构 #数据分析入门 #Pandas教程

觉得有用?分享给和你一样在学习数据分析的朋友。评论区留下你的问题,下一篇文章就可能回答你。

最新文章

随机文章