Pandas 数据结构 – DataFrame(快速上手)

Pandas 数据结构 – DataFrame:数据处理的瑞士军刀

在数据科学和分析领域,Pandas 是最常用、最核心的工具之一。它不仅让数据处理变得高效,还让代码更具可读性和表达力。而其中最核心的结构,就是 DataFrame —— 一个二维、可变大小、带标签的表格型数据结构。它就像一张 Excel 表格,但功能更强大,也更适合编程自动化处理。

如果你曾经用过 Excel 来整理销售数据、用户信息或实验记录,那么你对“表格”并不陌生。Pandas 的 DataFrame 正是这种思维的编程实现。它将行(记录)和列(字段)完美结合,支持复杂操作,如合并、分组、筛选、聚合等,是数据预处理和分析的基石。

接下来,我们就一步步揭开 DataFrame 的面纱,从创建到操作,再到实战应用。

创建 DataFrame 的多种方式

DataFrame 可以通过多种方式创建,最常见的是从字典、列表、NumPy 数组,甚至是文件中读取数据。

从字典创建

字典的键作为列名,值作为列的数据。这是最直观的方式之一。

import pandas as pd

data = {
    '姓名': ['张三', '李四', '王五', '赵六'],
    '年龄': [20, 22, 19, 21],
    '成绩': [88.5, 92.0, 76.5, 85.0],
    '是否及格': [True, True, False, True]
}

df = pd.DataFrame(data)

print(df.head())

注释:这段代码将一个 Python 字典转换为一个 DataFrame。键 '姓名'、'年龄' 等成为列名,对应的列表成为列数据。head() 方法显示前 5 行,用于快速预览数据。

从列表创建

如果数据是嵌套列表,每一行代表一条记录。

student_list = [
    ['张三', 20, 88.5, True],
    ['李四', 22, 92.0, True],
    ['王五', 19, 76.5, False],
    ['赵六', 21, 85.0, True]
]

df2 = pd.DataFrame(student_list, columns=['姓名', '年龄', '成绩', '是否及格'])

print(df2)

注释:这里我们用 columns 参数显式指定列名。如果省略,Pandas 会默认使用 0, 1, 2, 3 作为列名,这显然不直观。因此,建议总是指定列名。

从 NumPy 数组创建

当数据来自科学计算或机器学习项目时,常使用 NumPy 数组。Pandas 可以轻松将它们转换为 DataFrame。

import numpy as np

arr = np.random.randn(4, 4)

df3 = pd.DataFrame(arr, columns=['A', 'B', 'C', 'D'], index=['X', 'Y', 'Z', 'W'])

print(df3)

注释:index 参数用于设置行标签(行名),columns 用于设置列名。这使得 DataFrame 不仅有数据,还有清晰的结构标签。

DataFrame 的核心特性解析

DataFrame 之所以强大,是因为它具备多个核心特性,这些特性让它在处理真实世界数据时游刃有余。

行与列的标签化设计

与普通的数组不同,DataFrame 的行和列都有名称。这种标签化设计让你能用“名字”来操作数据,而不是记住位置。

print("列名:", df.columns)

print("行索引:", df.index)

df.rename(columns={'成绩': '分数'}, inplace=True)

df.index = ['学生1', '学生2', '学生3', '学生4']

注释:inplace=True 表示直接修改原对象,不返回新对象。rename 方法可用于修改列或行标签,让数据更具可读性。

支持异构数据类型

一个 DataFrame 的不同列可以是不同的数据类型。比如一列是整数(年龄),一列是浮点数(成绩),一列是布尔值(是否及格),甚至可以是字符串。

print(df.dtypes)

输出示例:

姓名      object
年龄       int64
分数     float64
是否及格    bool
dtype: object

注释:dtypes 属性显示每列的数据类型。object 通常表示字符串,int64 是整数,float64 是浮点数,bool 是布尔值。这种灵活性让 DataFrame 能处理真实世界中混杂的数据。

灵活的索引机制

DataFrame 支持两种索引方式:位置索引(基于整数)和标签索引(基于名称)。

print(df.iloc[0])        # 第 1 行(索引 0)
print(df.iloc[0:2])      # 第 1~2 行(索引 0 和 1)

print(df.loc['学生1'])   # 查找行标签为 '学生1' 的行
print(df.loc['学生1':'学生3'])  # 查找从 '学生1' 到 '学生3' 的行

注释:iloc 用于基于整数位置的索引,loc 用于基于标签的索引。使用 loc 时,如果行标签不存在,会抛出 KeyError;而 iloc 只要位置合法即可访问。

数据操作实战:筛选、排序与修改

掌握 DataFrame 的创建后,接下来就是如何操作数据。这是数据分析的核心环节。

条件筛选

你可以用布尔表达式筛选出满足特定条件的行。

high_scorers = df[df['分数'] > 85]

print(high_scorers)

filtered = df[(df['分数'] > 85) & (df['是否及格'] == True)]

print(filtered)

注释:布尔筛选非常强大。注意多条件必须用括号包裹,并且使用 &(与)、|(或)、~(非)而不是 andornot。这是因为 Pandas 重载了这些操作符以支持向量化运算。

排序

对数据进行排序是常见需求。DataFrame 支持按列排序。

sorted_df = df.sort_values(by='分数', ascending=False)

print(sorted_df)

sorted_df = df.sort_values(by=['年龄', '分数'], ascending=[True, False])

print(sorted_df)

注释:by 参数指定排序依据的列,ascending 控制升序或降序。多级排序时,会先按第一个列排序,再按第二个列进行次级排序。

数据修改与新增列

你可以在 DataFrame 中添加新列,或修改已有列。

def get_grade(score):
    if score >= 90:
        return 'A'
    elif score >= 80:
        return 'B'
    elif score >= 70:
        return 'C'
    else:
        return 'D'

df['等级'] = df['分数'].apply(get_grade)

print(df)

注释:apply() 方法对某一列的每个元素应用函数。这里我们自定义了一个 get_grade 函数,根据分数返回等级,并将其添加为新列。这是数据清洗和特征工程的典型操作。

DataFrame 的常用统计与聚合方法

在分析数据时,我们常常需要计算总和、平均值、最大值等统计量。

print(df.describe())

avg_age = df['年龄'].mean()
print(f"平均年龄:{avg_age:.2f}")

max_score = df['分数'].max()
print(f"最高分:{max_score}")

grouped = df.groupby('是否及格')['分数'].mean()
print(grouped)

注释:describe() 提供计数、均值、标准差、最小值、四分位数、最大值等统计信息。groupby() 是强大的分组操作,常用于按类别分析数据。

是否及格 平均分数
False 76.50
True 88.50

注释:groupby 会按“是否及格”分组,然后对每组的“分数”列计算均值,结果是一个新的 Series,清晰展示出及格与不及格学生的平均表现差异。

实战案例:处理真实数据文件

让我们模拟一个真实场景:读取一个 CSV 文件,进行清洗和分析。

df_sales = pd.read_csv('sales_data.csv')

print(df_sales.head())

print("缺失值统计:")
print(df_sales.isnull().sum())

df_sales['销售额'].fillna(df_sales['销售额'].mean(), inplace=True)

df_sales['利润率'] = df_sales['利润'] / df_sales['销售额']

total_sales_by_region = df_sales.groupby('地区')['销售额'].sum()

print(total_sales_by_region)

注释:read_csv() 是读取文件的核心方法。isnull().sum() 统计每列缺失值数量。fillna() 用于填充缺失值。groupby 与聚合结合,可快速生成关键业务指标。

总结

Pandas 数据结构 – DataFrame 是现代数据分析的基石。它不仅具备表格的直观结构,还融合了强大的编程能力,让你能用代码完成从数据加载、清洗、筛选、排序到聚合分析的全流程。

从创建、查看、修改到复杂操作,DataFrame 提供了一整套完整的工具链。无论是初学者还是中级开发者,只要掌握其核心概念和常用方法,就能高效处理各种数据任务。

记住:数据的价值不在于它有多大,而在于你能否从中提取出有意义的信息。而 DataFrame,正是你通往数据洞察的第一步。