Python
掌握 Pandas 2.0:初学者全面指南

掌握 Pandas 2.0:初学者全面指南

MoeNagy Dev

介绍新的 DataFrame:性能和功能的提升

增强型 DataFrame 概览:简化数据操作

在 Pandas 2.0 中,DataFrame 经历了重大改革,提供了一系列新功能和增强,使数据操作和分析更加简化。更新后的 DataFrame 提供了更加直观和高效的接口,使得处理复杂数据结构变得更加容易。

其中一个关键改进是引入了 DataFrame.vstack()DataFrame.hstack() 方法,可以轻松地垂直或水平堆叠多个 DataFrame。这简化了从多个来源组合数据的过程,减少了手动连接或合并操作的需求。

import pandas as pd
 
# 创建示例 DataFrame
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [4, 5, 6], 'B': [7, 8, 9]})
 
# 垂直堆叠 DataFrame
stacked_df = pd.DataFrame.vstack([df1, df2])
print(stacked_df)

输出:

   A  B
0  1  4
1  2  5
2  3  6
0  4  7
1  5  8
2  6  9

高效的内存管理:优化存储和减少开销

Pandas 2.0 引入了几项增强,以改善内存管理,减少 DataFrame 的整体占用空间。其中一个关键功能是引入了 DataFrame.astype() 方法,它现在支持自动内存优化。这意味着 Pandas 将智能地确定每个列的最合适的数据类型,在不影响数据的情况下减少内存使用。数据完整性

# 创建一个包含大整数值的DataFrame
df = pd.DataFrame({'A': [1_000_000, 2_000_000, 3_000_000]})
 
# 自动优化内存使用
df = df.astype('int32')
print(df.memory_usage())

输出:

Int32    12
dtype: int64

在上面的示例中,Pandas自动将列从int64转换为int32,将内存占用减少了一半,而没有造成任何数据损失。

改进的异构数据处理:无缝集成不同数据类型

Pandas 2.0增强了对异构数据的处理,允许在单个DataFrame中更无缝地集成不同的数据类型。这在处理包含数值、分类和文本信息混合的数据集时特别有用。

# 创建一个包含混合数据类型的DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': ['a', 'b', 'c'],
    'C': [True, False, True]
})
 
# 检查数据类型
print(df.dtypes)

输出:

A     int64
B    object
C       bool
dtype: object

Pandas 2.0中改进的异构数据处理确保了每一列都被分配了最合适的数据类型,使得在处理复杂数据集时无需进行大量的数据类型转换。

探索新的索引功能

引入MultiIndex:层次化数据组织

Pandas 2.0引入了对MultiIndex功能的重大改进,允许您在DataFrame中创建层次化的数据结构。这种强大的功能使您能够更有效地组织和访问数据,特别是在处理复杂的数据集时。

# 创建一个MultiIndex DataFrame
tuples = [
    ('bar', 'one'), ('bar', 'two'),
    ('baz', 'one'), ('baz', 'two'),
    ('foo', 'one'), ('foo', 'two')
]
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df = pd.DataFrame({'A': [1, 2, 3, 4, 5, 6], 'B': [10, 20, 30, 40, 50, 60]}, index=index)
print(df)

A B first second
bar one 1 10 two 2 20 baz one 3 30 two 4 40 foo one 5 50 two 6 60


多级索引 (Multi-Index) 提供了一种灵活的方式来处理层次化数据,允许您轻松地访问、过滤和操作不同层级的数据。

### 高级索引技术:掌握复杂数据结构

Pandas 2.0 扩展了索引功能,使得处理复杂数据结构更加容易。新的 `DataFrame.loc[]` 和 `DataFrame.iloc[]` 索引器现在支持更高级的操作,如使用多个条件进行布尔索引和高级基于标签的切片。

```python
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4, 5], 'B': [10, 20, 30, 40, 50]})

# 高级布尔索引
mask = (df['A'] > 2) & (df['B'] < 40)
filtered_df = df.loc[mask]
print(filtered_df)

输出:

   A   B
2  3  30

Pandas 2.0 中增强的索引功能提供了更大的灵活性和控制力,使您能够更高效地处理复杂的数据结构。

高效的数据切片和切块:利用索引的力量

Pandas 2.0 引入了几项数据切片和切块的改进,使得从 DataFrame 中提取和操作特定子集更加容易。新的 DataFrame.loc[]DataFrame.iloc[] 索引器现在支持更直观和强大的切片操作。

# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4, 5], 'B': [10, 20, 30, 40, 50]}, index=['a', 'b', 'c', 'd', 'e'])
 
# 基于标签的切片
print(df.loc['b':'d', 'A'])

输出:

b    2
c    3
d    4
Name: A, dtype: int64

Pandas 2.0 中增强的索引功能提供了更大的灵活性和控制力,使您能够更高效地处理复杂的数据结构。

数据整理

增强的数据清洗和预处理:简化数据准备

Pandas 2.0 引入了几项数据清洗和预处理的改进,使得准备数据进行分析变得更加容易。新的 DataFrame.dropna() 方法现在支持更高级的选项来处理缺失数据,包括根据指定的缺失值阈值删除行或列。

# 创建一个包含缺失值的示例 DataFrame
df = pd.DataFrame({'A': [1, 2, np.nan, 4, 5], 'B': [10, 20, 30, np.nan, 50]})
 
# 删除包含任何缺失值的行
df_cleaned = df.dropna()
print(df_cleaned)

输出:

     A     B
0  1.0  10.0
1  2.0  20.0
2  4.0  50.0

此外,Pandas 2.0 引入了新的数据转换函数,如 DataFrame.fillna()DataFrame.replace(),提供了更强大和灵活的选项来处理缺失数据和执行数据转换。

处理缺失数据:改进的插补和插值方法

Pandas 2.0 通过新的插补和插值方法增强了对缺失数据的处理。DataFrame.interpolate() 方法现在支持更广泛的插值技术,包括时间序列感知插值,使得处理复杂数据集中的缺失数据变得更加容易。

# 创建一个包含缺失值的示例 DataFrame
df = pd.DataFrame({'A': [1, 2, np.nan, 4, 5], 'B': [10, 20, 30, np.nan, 50]}, index=pd.date_range('2022-01-01', periods=5, freq='D'))
 
# 使用时间序列感知方法插值缺失值
df_interpolated = df.interpolate(method='time')
print(df_interpolated)

输出:

            A     B
2022-01-01  1.0  10.0
2022-01-02  2.0  20.0
2022-01-03  3.0  30.0
2022-01-04  4.0  40.0
2022-01-05  5.0  50.0

Pandas 2.0 中改进的缺失数据处理简化了数据准备过程,使您能够更有效地处理不完整的数据集。

自动化数据转换:利用向量化矢量化操作

Pandas 2.0 增强了矢量化操作的使用,使得执行复杂的数据转换变得更加简单高效。新的 DataFrame.apply() 方法现在支持更高级的功能,包括沿特定轴或单个元素应用自定义函数的能力。

# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [10, 20, 30]})
 
# 对每个元素应用自定义函数
df['C'] = df.apply(lambda x: x['A'] * x['B'], axis=1)
print(df)

输出:

   A   B   C
0  1  10  10
1  2  20  40
2  3  30  90

Pandas 2.0 中增强的矢量化操作使您能够编写更简洁高效的代码,减少手动、逐元素的数据转换的需求。

数据分析和可视化

强大的数据聚合: 利用分组和透视表解锁洞见

Pandas 2.0 引入了几项数据聚合的改进,使得从数据中提取洞见变得更加容易。新的 DataFrame.groupby()DataFrame.pivot_table() 方法现在支持更高级的选项,如多级分组和自动处理缺失值。

# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 1, 2, 1, 2], 'B': [10, 20, 30, 40, 50, 60], 'C': [1, 1, 2, 2, 3, 3]})
 
# 执行多级分组和聚合
grouped = df.groupby(['A', 'C'])['B'].mean()
print(grouped)

输出:

A  C
1  1    20.0
   2    30.0
   3    50.0
2  1    20.0
   2    40.0
   3    60.0
Name: B, dtype: float64

Pandas 2.0 中增强的数据聚合功能使得更容易发现数据中的洞见和模式,从而实现更复杂的数据分析。

交互式数据可视化: 将 Pandas 与绘图库集成

Pandas 2.0 简化了与流行的数据可视化库(如 Matplotlib 和 Plotly)的集成。新的 DataFrame.plot() 方法现在支持与这些库更无缝的集成。

# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4, 5], 'B': [10, 20, 30, 40, 50]})
 
# 创建一个交互式折线图
df.plot(x='A', y='B', kind='line')

Pandas 2.0 中增强的数据可视化功能使您能够生成更加信息丰富和引人入胜的图表,从而更好地探索数据并传达洞见。

高级统计分析:利用 Pandas 进行预测性建模

Pandas 2.0 增强了与统计和机器学习库的集成,使您能够直接在 Pandas 工作流中执行高级数据分析和预测性建模。新的 DataFrame.apply() 方法现在支持应用可以利用外部库(如 scikit-learn 或 statsmodels)的自定义函数。

函数

函数是执行特定任务的可重用代码块。它们允许您将代码分解为更小、更易管理的部分,从而使代码更易于阅读、理解和维护。

定义函数

在 Python 中定义函数时,使用 def 关键字,后跟函数名、一组括号和一个冒号。函数体缩进,包含在调用函数时将执行的代码。

def greet(name):
    print(f"Hello, {name}!")

在这个例子中,greet 函数接受一个参数 name,并使用提供的名称打印一条问候消息。

函数参数

函数可以接受一个或多个参数,这些参数是在调用函数时传递给函数的变量。参数在函数定义的括号内定义。

def calculate_area(length, width):
    area = length * width
    print(f"The area of the rectangle is {area} square units.")
 
calculate_area(5, 10)  # 输出: The area of the rectangle is 5.

0 平方单位。


在这个例子中,`calculate_area` 函数接受两个参数 `length` 和 `width`,并计算矩形的面积。

### 返回语句

函数也可以返回值,这些值可以在代码的其他部分使用。要返回一个值,需要使用 `return` 关键字。

```python
def add_numbers(a, b):
    # 返回 a 和 b 的和
    return a + b

result = add_numbers(3, 4)
print(result)  # 输出: 7

在这个例子中,add_numbers 函数接受两个参数 ab,并返回它们的和。

默认参数

你也可以为函数参数定义默认值,当调用函数时没有提供该参数时,将使用默认值。

def greet(name, message="Hello"):
    # 打印问候语
    print(f"{message}, {name}!")
 
greet("Alice")  # 输出: Hello, Alice!
greet("Bob", "Hi")  # 输出: Hi, Bob!

在这个例子中,greet 函数有一个默认参数 message,默认值为 "Hello" 。如果在调用函数时没有提供 message 参数,则使用默认值。

可变长参数

有时,你可能需要编写可以接受可变数量参数的函数。你可以使用 *args 语法来实现这一点。

def sum_numbers(*args):
    # 计算所有数字的和
    total = 0
    for num in args:
        total += num
    return total
 
print(sum_numbers(1, 2, 3))  # 输出: 6
print(sum_numbers(4, 5, 6, 7, 8))  # 输出: 30

在这个例子中,sum_numbers 函数可以接受任意数量的参数,这些参数被收集到一个名为 args 的元组中。函数然后计算元组中所有数字的和并返回结果。

Lambda 函数(匿名函数)

Python 也支持匿名函数,称为 lambda 函数,这些是小型的单行函数,可以在不定义名称的情况下定义。

square = lambda x: x ** 2
print(square(5))  # 输出: 25
 
add_numbers = lambda a, b: a + b
print(add_numbers(3, 4))  # 输出: 7

在这个例子中,square 函数被定义为一个 lambda 函数。

模块和包

在 Python 中,模块和包用于组织和重用代码。

模块

模块是包含 Python 定义和语句的文件。模块允许你以逻辑方式组织你的代码,并使其更易于维护和共享。

# my_module.py
def greet(name):
    print(f"你好, {name}!")
 
# main.py
import my_module
my_module.greet("Alice")  # 输出: 你好, Alice!

在这个例子中,greet 函数定义在 my_module.py 文件中,然后在 main.py 文件中导入并使用。

包是一种将模块组织成层次目录结构的方式,允许你创建更大、更复杂的应用程序。

my_package/
    __init__.py
    math_utils.py
    string_utils.py

在这个例子中,my_package 是一个包,包含两个模块: math_utils.pystring_utils.py__init__.py 文件是一个特殊的文件,告诉 Python 这个目录是一个包。

# main.py
from my_package import math_utils, string_utils
 
result = math_utils.add(2, 3)
print(result)  # 输出: 5
 
reversed_string = string_utils.reverse_string("hello")
print(reversed_string)  # 输出: "olleh"

在这个例子中,math_utilsstring_utils 模块从 my_package 包中导入,并在 main.py 文件中使用。

文件 I/O

Python 提供了内置函数,用于读取和写入文件。

读取文件

要读取文件的内容,可以使用 open() 函数打开文件,然后使用 read() 方法读取其内容。

with open("example.txt", "r") as file:
    content = file.read()
    print(content)

在这个例子中,open() 函数用于以读取模式 ("r") 打开 example.txt 文件,然后使用 read() 方法读取其内容。### 写入文件

要写入文件,可以使用 open() 函数以写入模式 ("w") 打开文件,并使用 write() 方法将数据写入文件。

with open("output.txt", "w") as file:
    file.write("This is some text to be written to the file.")

在这个例子中,open() 函数用于以写入模式打开 output.txt 文件,write() 方法用于将字符串写入文件。

文件模式

open() 函数接受第二个参数,指定以哪种模式打开文件。以下是一些常见的文件模式:

  • "r": 读取模式(默认)
  • "w": 写入模式(覆盖现有文件)
  • "a": 追加模式(添加到文件末尾)
  • "r+": 读写模式
  • "b": 二进制模式(用于非文本文件)

处理文件异常

处理文件相关的异常很重要,例如文件不存在或没有权限访问。可以使用 try-except 块来捕获和处理这些异常。

try:
    with open("non_existent_file.txt", "r") as file:
        content = file.read()
        print(content)
except FileNotFoundError:
    print("The file does not exist.")

在这个例子中,如果 non_existent_file.txt 文件不存在,FileNotFoundError 异常将被捕获,并打印出相应的消息。

结论

在本教程中,您已经学习了各种 Python 概念,包括函数、模块、包和文件 I/O。这些特性对于编写更复杂和有组织的 Python 程序非常重要。通过理解和应用这些概念,您可以创建更健壮和可维护的代码。

记住,提高 Python 技能的最佳方式是定期练习并尝试不同的技术和方法。继续探索 Python 丰富的库和模块生态系统,并在需要帮助时不要犹豫向蓬勃发展的 Python 社区寻求帮助。当你遇到挑战时。

祝你编码愉快!

MoeNagy Dev.

Example Code

# This is a Python script
# 这是一个Python脚本
import random
 
# Generate a random number between 1 and 100
# 生成一个1到100之间的随机数
random_number = random.randint(1, 100)
 
# Print the random number
# 打印随机数
print(f"The random number is: {random_number}")