Skip to content
清晨的一缕阳光
返回

机器学习速成·前置(三):Pandas DataFrame 上手——创建、取值与引用

机器学习速成·前置(三):Pandas DataFrame 上手——创建、取值与引用

本文参考 Google ML Crash Course 前置工作 - Pandas DataFrame UltraQuick Tutorial 撰写。这篇不是 DataFrames 的完整教程,而是完成 MLCC 后续练习所必需的最小子集


一、DataFrame 是什么?

DataFrame(数据帧) 是 pandas API 的核心数据结构。你可以把它理解为一块内存里的电子表格

就像 Excel 一样,它把”二维表”和强大的分析能力绑在一起,是机器学习里加载、清洗、浏览数据的主力。


二、导入 NumPy 和 pandas

import numpy as np
import pandas as pd

为什么又要 NumPy?因为 DataFrame 的数据很多来自 NumPy 数组,两者常常一起用。


三、创建 DataFrame

pd.DataFrame(...) 实例化一个 DataFrame,通常传两个参数:

  1. 数据源(如一个 NumPy 数组);
  2. 列名列表
# 创建并填充一个 5x2 的 NumPy 数组
my_data = np.array([[0, 3], [10, 7], [20, 9], [30, 14], [40, 15]])

# 保存两列的列名
my_column_names = ['temperature', 'activity']

# 创建 DataFrame
my_dataframe = pd.DataFrame(data=my_data, columns=my_column_names)

# 打印整个 DataFrame
print(my_dataframe)

输出后你就得到一个 5 行 2 列、带表头的表格:temperatureactivity 两列,行为 0~4 编号。

⚠️ 注意:后续代码会继续使用这些变量,不要在同一 notebook 里重新定义它们。


四、给 DataFrame 新增一列

给已有 DataFrame 加列非常简单:直接给一个新列名赋值即可。

# 新建名为 adjusted 的列,值是 activity 列 + 2
my_dataframe["adjusted"] = my_dataframe["activity"] + 2

print(my_dataframe)

幂等、直观——pandas 会对整列做向量的逐元素运算,一步生成新列。


五、取出 DataFrame 的子集

pandas 提供了多种隔离行/列/切片/单元格的方式:

print("Rows #0, #1, and #2:")
print(my_dataframe.head(3), '\n')      # 前 3 行

print("Row #2:")
print(my_dataframe.iloc[[2]], '\n')     # 按位置取第 2 行(iloc)

print("Rows #1, #2, and #3:")
print(my_dataframe[1:4], '\n')          # 行切片(左闭右开)

print("Column 'temperature':")
print(my_dataframe['temperature'])       # 按列名取整列
操作写法返回
前 N 行df.head(N)一个 DataFrame(含表头)
按行号取行df.iloc[[i]]指定行
行切片df[a:b]第 a 到 b−1 行(左闭右开)
取整列df['列名']该列数据

六、动手练习:建一个随机 DataFrame

按如下要求做一个小任务(用到前述 NumPy 基础):

  1. 创建 3×4 的 DataFrame,列名是 EleanorChidiTahaniJason,每个单元格填一个 0~100(含) 的随机整数;
  2. 输出:整个 DataFrame,以及 第 1 行 Eleanor的那个单元格;
  3. 新建第 5 列 Janet,值为 TahaniJason 两列的逐行求和

参考解法:

my_column_names = ['Eleanor', 'Chidi', 'Tahani', 'Jason']

# 3x4 随机整数(0~100,含)
my_data = np.random.randint(low=0, high=101, size=(3, 4))

df = pd.DataFrame(data=my_data, columns=my_column_names)
print(df)

# 第 1 行 Eleanor 列的值
print("Second row of the Eleanor column: %d\n" % df['Eleanor'][1])

# 新增列:两列逐行求和
df['Janet'] = df['Tahani'] + df['Jason']
print(df)

体会一下:列与列之间可以直接做算术运算,这正是后续特征工程的高频操作。


七、引用 vs 拷贝:一个微妙但重要的区别

复用一个 DataFrame 有两种方式,结果截然不同:

7.1 引用(Reassignment):会”联动”

reference_to_df = df   # 只是给同一个对象换了个名字
df.at[1, 'Jason'] = df['Jason'][1] + 5

print(df['Jason'][1])            # 更新后的值
print(reference_to_df['Jason'][1])  # 引用也被改动了!

因为 reference_to_dfdf 指向同一份内存,改任何一个,另一个都跟着变。

7.2 拷贝(.copy()):互不影响

copy_of_my_dataframe = my_dataframe.copy()   # 真正的独立拷贝
my_dataframe.at[1, 'activity'] = my_dataframe['activity'][1] + 3

print(my_dataframe['activity'][1])            # 被更新
print(copy_of_my_dataframe['activity'][1])    # 拷贝仍保持原值

.copy() 生成一份完全独立的副本,两者从此互不影响。

写法改一人是否影响另一人
引用new_df = df✅ 会影响(同一份内存)
拷贝new_df = df.copy()❌ 不影响(独立副本)

一句话记住:”=“只是多了个名字,“.copy()”才是真复制。 处理共享数据时务必分清,否则极易改动到”没想到会被改”的对象。


八、小结

能力关键方法注意点
创建pd.DataFrame(data=数组, columns=列名)列名与数据列数要一一对应
加列df["新列名"] = 表达式支持列间向量运算
前几行df.head(N)返回 DataFrame
按行取df.iloc[[i]]位置索引
行切片df[a:b]左闭右开
取列df["列名"]返回整列
复用= 是引用、.copy() 是拷贝引用会联动、拷贝独立

一句话:DataFrame 就是”内存里的Excel”——用 pd.DataFrame 建表、直接赋值 df["新列"] 加列、head/iloc/切片取任意子集;但要记住 = 只是多起个名字,想真正复制得用 .copy()


分享这篇文章到:

上一篇文章
机器学习速成·线性回归(1/4):线性回归——从方程、参数到多特征模型
下一篇文章
机器学习速成·前置(二):NumPy 上手——数组、随机数与广播