python学习DataFrame数据结构

发布于:2025-07-12 ⋅ 阅读:(17) ⋅ 点赞:(0)

1、什么是 DataFrame?

  • Pandas 是 Python 中用于数据处理和分析的核心库之一,其最核心的数据结构就是 DataFrame。它是类似于 Excel 表格或 SQL 表的二维带标签的数据结构,非常适合进行数据清洗、筛选、统计、合并等操作。
  • DataFrame 是一个带有行索引(index)和列名(columns)的二维表格型结构。每一列可以是不同的类型(如整数、浮点数、字符串等),类似于数据库中的“表”或 Excel 的一张工作表。

2、DataFrame 的基本结构

  • 我们可以把它想象成一个表格,比如下面这个例子:

    姓名 年龄 性别 城市
    张三 25 北京
    李四 30 上海
    王五 28 广州
  • 行索引(index):默认为 0, 1, 2…,也可以自定义。

  • 列名(columns):即字段名,如 “姓名”, “年龄” 等。 数据(values):每个单元格里的具体值。

3、创建 DataFrame 的常见方式

3.1、使用字典创建(最常用)

import pandas as pd

data = {
    '姓名': ['张三', '李四', '王五'],
    '年龄': [25, 30, 28],
    '性别': ['男', '女', '男'],
    '城市': ['北京', '上海', '广州']
}

df = pd.DataFrame(data)
print(df)
  • 输出:
   姓名  年龄 性别   城市
0  张三  25   男   北京
1  李四  30   女   上海
2  王五  28   男   广州

3.2、指定行索引

df = pd.DataFrame(data, index=['a', 'b', 'c'])

3.3、从 NumPy 数组创建

import numpy as np

arr = np.array([
    ['张三', 25, '男', '北京'],
    ['李四', 30, '女', '上海'],
    ['王五', 28, '男', '广州']
])

df = pd.DataFrame(arr, columns=['姓名', '年龄', '性别', '城市'])

4、常用属性和方法

在这里插入图片描述

5、DataFrame 的主要功能(可执行的操作)

5.1、数据筛选

# 筛选年龄大于 28 的人
df[df['年龄'] > 28]

# 筛选城市为北京的人
df[df['城市'] == '北京']

# 多条件筛选
df[(df['性别'] == '男') & (df['年龄'] < 30)]

5.2、新增列

# 添加一个“是否成年”的布尔列
df['是否成年'] = df['年龄'] >= 18

5.3、修改列名

df.rename(columns={'姓名': '名字'}, inplace=True)

5.4、删除列或行

# 删除列
df.drop('城市', axis=1, inplace=True)

# 删除行
df.drop([0, 1], axis=0, inplace=True)

5.5、排序

# 按年龄排序
df.sort_values(by='年龄', ascending=False, inplace=True)

5.6、分组聚合(groupby)

# 按性别分组并计算平均年龄
df.groupby('性别')['年龄'].mean()

5.7、合并与连接(merge/join)

df1 = pd.DataFrame({'id': [1, 2, 3], 'name': ['A', 'B', 'C']})
df2 = pd.DataFrame({'id': [1, 2, 4], 'score': [90, 80, 85]})

# 内连接
merged_df = pd.merge(df1, df2, on='id', how='inner')

6、DataFrame vs Series

类型 描述 示例
DataFrame 二维结构,多行多列 整个表格
Series 一维结构,单列或某一行 df[‘年龄’] 或 df.iloc[0]

7、DataFrame 底层实现原理(简要)

  • 实际上,DataFrame 是由多个 Series 组成的字典结构(类似 dict[str, Series])。
  • 所有列共享相同的索引。
  • 支持向量化运算,底层使用的是 NumPy。
  • 可以高效处理大规模数据,并支持缺失值处理(NaN)、时间序列等功能。

8、DataFrame的方括号为什么可以做这么复杂的操作?

8.1、核心机制:布尔索引(Boolean Masking)

  • DataFrame的方括号能实现复杂的数据筛选,是因为 pandas 库的 DataFrame 结构支持布尔索引(Boolean Indexing),并且利用了 Python 的 运算符重载 和 NumPy 的向量化计算机制。
  • pandas 的 DataFrame 允许通过一个布尔值数组(True/False 组成的数组) 来筛选数据。
  • 代码
    import pandas as pd
    
    df = pd.DataFrame({
        "年龄": [25, 35, 40, 28],
        "性别": ["男", "女", "男", "男"]
    })
    
    # 生成布尔数组
    mask = (df["年龄"] > 30) & (df["性别"] == "男")
    print(mask)
    
  • 输出
    0    False
    1    False
    2     True
    3    False
    dtype: bool
    
  • mask 是一个布尔数组,True 表示该行满足条件,False 表示不满足。
  • 通过 df[mask],pandas 会返回所有 mask 为 True 的行:
    filtered_data = df[mask]  # 等价于 df[(df["年龄"] > 30) & (df["性别"] == "男")]
    print(filtered_data)
    
  • 输出
       年龄 性别
    2  40  男
    
  • 手动构建一个布尔数组也可以实现相同的输出
    # 需要注意手动构建的布尔数组的元素个数需要和DataFrame的条数(行数)一致,不然会报错
    mask_hand = [False,False,True,False]
    filtered_data = df[mask_hand]
    print(filtered_data)
    
  • 输出
       年龄 性别
    2  40  男
    

8.2、关键点解析

(1) 为什么 df["年龄"] > 30 返回布尔数组?

  • df["年龄"] 是一个 pandas.Series 对象。
  • 比较操作(如 >)会被 向量化(逐元素计算),返回一个同长度的布尔数组:
    print(df["年龄"] > 30)
    
    输出:
    0    False
    1    True
    2    True
    3    False
    dtype: bool
    

(2) 为什么 & 能用于条件组合?

  • & 是 Python 的 按位与运算符,但在 pandas 中它被重载为 逻辑与(需用括号保证优先级)。
  • pandas 会逐元素比较两个布尔数组:
    (df["年龄"] > 30) & (df["性别"] == "男")
    
    等价于:
    [False, True, True, False] & [True, False, True, True] = [False, False, True, False]
    

(3) 为什么用 & 而不是 and

  • and 是 Python 的原生逻辑运算符,只能用于标量(单个 True/False),不能处理数组。
  • &pandas/NumPy 重载的运算符,支持向量化操作。

8.3、语法糖:方括号的魔法

df[condition] 的方括号看似简单,但实际是 pandas索引器(Indexer) 的语法糖。它的底层逻辑是:

  1. 先计算括号内的条件表达式,生成布尔数组。
  2. 将布尔数组传递给 DataFrame.__getitem__() 方法,返回匹配的行。

8.4、对比原生 Python 实现

  • 如果用原生 Python 实现类似功能,代码会冗长许多:
    filtered_rows = []
    for i in range(len(df)):
        if df.loc[i, "年龄"] > 30 and df.loc[i, "性别"] == "男":
            filtered_rows.append(df.loc[i])
    filtered_data = pd.DataFrame(filtered_rows)
    
  • pandas 的向量化操作让代码更简洁高效!

8.5、注意事项

  1. 括号不可省略

    # 错误写法(运算符优先级问题)
    df[df["年龄"] > 30 & df["性别"] == "男"]  # 等价于 df[df["年龄"] > (30 & df["性别"]) == "男"]
    
    # 正确写法
    df[(df["年龄"] > 30) & (df["性别"] == "男")]
    
  2. 多条件组合时用 |(或)、~(非)

    df[(df["年龄"] > 30) | (df["性别"] == "女")]
    

9、总结

DataFrame的功能

功能 用途说明
创建 DataFrame 用字典、数组、文件导入等
筛选与查询 df[条件], .loc[], .iloc[]
修改结构 增删改列、修改索引
数据统计与分析 describe(), groupby(), mean()
合并与清洗 merge(), dropna(), fillna()
输出与保存 to_csv(), to_excel()

DataFrame的计算

关键点 说明
布尔索引 df[布尔数组] 返回 True 对应的行
向量化操作 Series 的比较/逻辑运算自动逐元素计算
运算符重载 &|~pandas 重载为逻辑运算
语法糖 方括号 [] 底层调用 __getitem__ 方法
  • 这种设计使得 pandas 能够用简洁的语法实现高效的复杂筛选,是数据科学的强大工具!

网站公告

今日签到

点亮在社区的每一天
去签到