python学习DataFrame数据结构

文章目录

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、使用字典创建(最常用)

python 复制代码
import pandas as pd

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

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

3.2、指定行索引

python 复制代码
df = pd.DataFrame(data, index=['a', 'b', 'c'])

3.3、从 NumPy 数组创建

python 复制代码
import numpy as np

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

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

4、常用属性和方法

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

5.1、数据筛选

python 复制代码
# 筛选年龄大于 28 的人
df[df['年龄'] > 28]

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

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

5.2、新增列

python 复制代码
# 添加一个"是否成年"的布尔列
df['是否成年'] = df['年龄'] >= 18

5.3、修改列名

python 复制代码
df.rename(columns={'姓名': '名字'}, inplace=True)

5.4、删除列或行

python 复制代码
# 删除列
df.drop('城市', axis=1, inplace=True)

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

5.5、排序

python 复制代码
# 按年龄排序
df.sort_values(by='年龄', ascending=False, inplace=True)

5.6、分组聚合(groupby)

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

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

python 复制代码
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 组成的数组) 来筛选数据。

  • 代码

    python 复制代码
    import pandas as pd
    
    df = pd.DataFrame({
        "年龄": [25, 35, 40, 28],
        "性别": ["男", "女", "男", "男"]
    })
    
    # 生成布尔数组
    mask = (df["年龄"] > 30) & (df["性别"] == "男")
    print(mask)
  • 输出

    txt 复制代码
    0    False
    1    False
    2     True
    3    False
    dtype: bool
  • mask 是一个布尔数组,True 表示该行满足条件,False 表示不满足。

  • 通过 df[mask],pandas 会返回所有 mask 为 True 的行:

    python 复制代码
    filtered_data = df[mask]  # 等价于 df[(df["年龄"] > 30) & (df["性别"] == "男")]
    print(filtered_data)
  • 输出

    txt 复制代码
       年龄 性别
    2  40  男
  • 手动构建一个布尔数组也可以实现相同的输出

    python 复制代码
    # 需要注意手动构建的布尔数组的元素个数需要和DataFrame的条数(行数)一致,不然会报错
    mask_hand = [False,False,True,False]
    filtered_data = df[mask_hand]
    print(filtered_data)
  • 输出

    txt 复制代码
       年龄 性别
    2  40  男

8.2、关键点解析

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

  • df["年龄"] 是一个 pandas.Series 对象。

  • 比较操作(如 >)会被 向量化 (逐元素计算),返回一个同长度的布尔数组:

    python 复制代码
    print(df["年龄"] > 30)

    输出:

    复制代码
    0    False
    1    True
    2    True
    3    False
    dtype: bool

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

  • & 是 Python 的 按位与运算符 ,但在 pandas 中它被重载为 逻辑与(需用括号保证优先级)。

  • pandas 会逐元素比较两个布尔数组:

    python 复制代码
    (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 实现类似功能,代码会冗长许多:

    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. 括号不可省略

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

    python 复制代码
    df[(df["年龄"] > 30) | (df["性别"] == "女")]

9、总结

DataFrame的功能

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

DataFrame的计算

关键点 说明
布尔索引 df[布尔数组] 返回 True 对应的行
向量化操作 Series 的比较/逻辑运算自动逐元素计算
运算符重载 &、`
语法糖 方括号 [] 底层调用 __getitem__ 方法
  • 这种设计使得 pandas 能够用简洁的语法实现高效的复杂筛选,是数据科学的强大工具!
相关推荐
thusloop38 分钟前
380. O(1) 时间插入、删除和获取随机元素
数据结构·算法·leetcode
Otaku love travel1 小时前
实施运维文档
运维·windows·python
测试老哥1 小时前
软件测试之单元测试
自动化测试·软件测试·python·测试工具·职场和发展·单元测试·测试用例
future14121 小时前
游戏开发日记
数据结构·学习·c#
presenttttt2 小时前
用Python和OpenCV从零搭建一个完整的双目视觉系统(六 最终篇)
开发语言·python·opencv·计算机视觉
wjcurry2 小时前
完全和零一背包
数据结构·算法·leetcode
棱镜研途3 小时前
学习笔记丨卷积神经网络(CNN):原理剖析与多领域Github应用
图像处理·笔记·学习·计算机视觉·cnn·卷积神经网络·信号处理
qq_433554543 小时前
C++ 选择排序、冒泡排序、插入排序
数据结构
python_tty3 小时前
排序算法(一):冒泡排序
数据结构·算法·排序算法
测试19983 小时前
软件测试之压力测试总结
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·压力测试