Python
Pandas Sorted: 高效排序的初学者指南

Pandas Sorted: 高效排序的初学者指南

MoeNagy Dev

在 Pandas 中对数据进行排序

排序在数据分析中的重要性

排序是数据分析中的一个基本操作,它有助于以有意义的方式组织数据。它促进了数据探索和理解,并为进一步的分析和可视化做好准备。通过对数据进行排序,您可以更轻松地识别模式、趋势和异常值,从而获得更好的洞见和决策。

对单列 Series 进行排序

在 Pandas 中对单列 Series 进行排序是一个简单的过程。您可以按升序或降序对数据进行排序,并在排序过程中处理缺失值。

按升序排序

import pandas as pd
 
# 创建一个示例 Series
s = pd.Series([3, 1, 4, 2, None])
 
# 按升序对 Series 进行排序
sorted_s = s.sort_values()
print(sorted_s)

输出:

1    1.0
3    2.0
0    3.0
2    4.0
4    NaN
dtype: float64

按降序排序

# 按降序对 Series 进行排序
sorted_s = s.sort_values(ascending=False)
print(sorted_s)

输出:

2    4.0
0    3.0
3    2.0
1    1.0
4    NaN
dtype: float64

在排序过程中处理缺失值

默认情况下,Pandas 会将缺失值 (NaN) 放在排序后的 Series 的末尾,无论排序顺序如何。您可以使用 na_position 参数控制缺失值的位置。

# 将缺失值放在排序后的 Series 的开头
sorted_s = s.sort_values(na_position='first')
print(sorted_s)

输出:

4    NaN
1    1.0
3    2.0
0    3.0
2    4.0
dtype: float64

对多列 DataFrame 进行排序

排序多列 DataFrame 涉及指定要排序的列,并控制每列的排序顺序。

按单列排序

# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [3, 1, 4, 2], 'B': [1, 2, 3, 4]})
 
# 按列 'A' 对 DataFrame 进行排序
sorted_df = df.sort_values(by='A')
print(sorted_df)

输出:

   A  B
1   1  2
3   2  4
0   3  1
2   4  3

按多列排序

# 按列 'A' 和 'B' 对 DataFrame 进行排序
sorted_df = df.sort_values(by=['A', 'B'])
print(sorted_df)

输出:

   A  B
1   1  2
0   3  1
2   4  3
3   4  4

控制每列的排序顺序

# 按 'A' 列升序, 'B' 列降序对 DataFrame 进行排序
sorted_df = df.sort_values(by=['A', 'B'], ascending=[True, False])
print(sorted_df)

输出:

   A  B
1   1  2
0   3  1
3   4  4
2   4  3

使用自定义键函数进行排序

您可以使用自定义键函数来控制 Pandas 中的排序行为。这允许您根据特定需求应用复杂的排序逻辑。

使用 Lambda 函数作为键

# 按列 'A' 的绝对值对 DataFrame 进行排序
sorted_df = df.sort_values(by='A', key=lambda x: x.abs())
print(sorted_df)

输出:

   A  B
1   1  2
3   2  4
0   3  1
2   4  3

使用自定义函数应用复杂的排序逻辑

def custom_sort_key(x):
    # 先按列 'A' 的平方排序,
    # 然后按列 'B' 的值排序
    return (x['A'] ** 2, x['B'])
 
sorted_df = df.sort_values(by=['A', 'B'], key=custom_sort_key)
print(sorted_df)

输出:

   A  B
1   1  2
0   3  1
2   4  3
3   4  4

在排序过程中保留原始索引

默认情况下, Pandas 会修改排序后数据的索引。如果您想保留原始索引,可以使用 ignore_index 参数或在排序后重置索引。

保留原始索引

# 对 DataFrame 进行排序,并保留原始索引。

保留原始索引对 DataFrame 进行排序

sorted_df = df.sort_values(by='A', ignore_index=False)
print(sorted_df)

输出:

   A  B
0   1  2
1   3  1
2   4  3
3   2  4

重置索引后排序

# 对 DataFrame 进行排序并重置索引
sorted_df = df.sort_values(by='A').reset_index(drop=True)
print(sorted_df)

输出:

   A  B
0   1  2
1   2  4
2   3  1
3   4  3

部分数据排序

有时,您可能需要只对 DataFrame 中的部分行或列进行排序。Pandas 提供了灵活的处理方式。

对部分行或列进行排序

# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [3, 1, 4, 2], 'B': [1, 2, 3, 4], 'C': [10, 20, 30, 40]})
 
# 只对 'A' 列大于 2 的行进行排序
sorted_df = df[df['A'] > 2].sort_values(by='A')
print(sorted_df)

输出:

   A  B   C
0   3  1  10
2   4  3  30

处理部分数据中的缺失值

# 创建一个包含缺失值的 DataFrame
df = pd.DataFrame({'A': [3, 1, None, 2], 'B': [1, 2, 3, 4]})
 
# 只对 'A' 列非缺失值的行进行排序
sorted_df = df.loc[df['A'].notna()].sort_values(by='A')
print(sorted_df)

输出:

     A  B
1    1  2
3    2  4
0    3  1

排序分类数据

Pandas 提供了特殊的处理方式来对分类数据进行排序,允许您在排序过程中控制分类的顺序。

根据分类顺序进行排序

import pandas as pd
 
# 创建一个分类 Series
s = pd.Series([1, 2, 3, 1], dtype='category')
s = s.cat.reorder_categories([3, 1, 2])
 
# 对分类 Series 进行排序
sorted_s = s.sort_values()
print(sorted_s)

输出:

0    1
3    1
1    2
2    3
dtype: category
Categories (3, int64): [3, 1, 2]

自定义分类顺序进行排序

# 创建一个包含分类列的 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 1], 'B': ['a', 'b', 'c', 'a']})
df['B'] = df['B'].astype('category')
```以下是中文翻译版本:
 
```python
# 将列 'B' 的类别重新排序为 ['c', 'b', 'a']
df['B'] = df['B'].cat.reorder_categories(['c', 'b', 'a'])
 
# 按列 'B' 对 DataFrame 进行排序
sorted_df = df.sort_values(by='B')
print(sorted_df)

输出:

   A  B
2  3  c
1  2  b
0  1  a
3  1  a

对日期时间和时间差数据进行排序

Pandas 提供了高效的处理日期、时间和时间差数据的排序功能。这在处理时间序列数据时特别有用。

对日期和时间数据进行排序

import pandas as pd
 
# 创建一个包含日期时间数据的 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': pd.to_datetime(['2023-04-01', '2023-03-15', '2023-04-15', '2023-03-01'])})
 
# 按日期时间列 'B' 对 DataFrame 进行排序
sorted_df = df.sort_values(by='B')
print(sorted_df)

输出:

   A         B
3  4 2023-03-01
1  2 2023-03-15
0  1 2023-04-01
2  3 2023-04-15

处理时间相关的排序场景

# 创建一个包含时间差数据的 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': pd.to_timedelta(['1 days', '2 hours', '3 minutes', '4 seconds'])})
 
# 按时间差列 'B' 对 DataFrame 进行排序
sorted_df = df.sort_values(by='B')
print(sorted_df)

输出:

   A           B
3  4 0 days 00:00:04
1  2 0 days 00:02:00
2  3 0 days 00:03:00
0  1 1 days 00:00:00

对大型数据集进行高效排序

在处理大型数据集时,利用 Pandas 优化的排序算法并考虑内存和性能影响是很重要的。

利用 Pandas 优化的排序算法

# 使用 Pandas 优化的排序算法对大型 DataFrame 进行排序
large_df = pd.DataFrame({'A': np.random.randint(0, 1000000, size=1000000), 'B': np.random.randint(0, 1000000, size=1000000)})
sorted_df = large_df.sort_values(by='A')

内存和性能的考虑

在对大型数据集进行排序时,您可能需要考虑以下因素:

  • 内存使用: 排序可能会占用大量内存,尤其是对于大型 DataFrame。监控内存使用情况,并考虑使用.

优化内存消耗

  • 内存消耗: 虽然 Pandas 的排序算法通常很高效,但对于非常大的数据集,您可能需要探索其他排序方法或库,如 Dask 或 Vaex,它们专为大数据处理而设计。

将排序与其他 Pandas 操作结合使用

排序通常与其他 Pandas 操作(如分组、过滤和聚合)结合使用,以准备数据进行进一步分析。

在分组、过滤或聚合之前进行排序

# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 1, 2], 'B': [10, 20, 30, 40, 50]})
 
# 在分组和聚合之前对 DataFrame 进行排序
sorted_df = df.sort_values(by='A')
grouped = sorted_df.groupby('A')['B'].mean()
print(grouped)

输出:

A
1    25.0
2    35.0
3    30.0
Name: B, dtype: float64

将排序集成到数据转换管道中

# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [3, 1, 4, 2], 'B': [1, 2, 3, 4]})
 
# 将排序与其他 Pandas 操作结合使用
transformed_df = (
    df
    .sort_values(by='A')
    .groupby('A')['B']
    .sum()
    .reset_index()
)
print(transformed_df)

输出:

   A   B
0  1   2
1  2   4

变量和数据类型

字符串

Python 中的字符串是一系列字符。它们可以使用单引号 '、双引号 " 或三引号 '''""" 定义。下面是一个示例:

my_string = "Hello, World!"
print(my_string)  # 输出: Hello, World!

您可以使用索引访问字符串中的单个字符,也可以使用切片获取字符串的子集。

my_string = "Python is awesome!"
print(my_string[0])  # 输出: P
print(my_string[7:13])  # 输出: is awe

数字

Python 支持三种主要的数字数据类型: int (整数)、float (浮点数)和 complex (复数)。下面是一个示例:

x = 42
y = 3.14
z = 2 + 3j
print(x)  # 输出: 42
print(y)  # 输出: 3.14
print(z)  # 输出: (2+3j)
x = 42  # 整数
y = 3.14  # 浮点数
z = 2 + 3j  # 复数
 
print(x)  # 输出: 42
print(y)  # 输出: 3.14
print(z)  # 输出: (2+3j)

布尔值

布尔值是 Python 中的一种特殊数据类型,它只能有两个值:TrueFalse。它们通常用于条件语句和逻辑运算中。

is_sunny = True
is_raining = False
 
print(is_sunny)  # 输出: True
print(is_raining)  # 输出: False

列表

Python 中的列表是有序的元素集合。它们可以包含不同数据类型的元素,包括其他列表。下面是一个例子:

my_list = [1, 2.5, "three", True]
print(my_list)  # 输出: [1, 2.5, 'three', True]
print(my_list[2])  # 输出: 'three'

你还可以对列表执行各种操作,如切片、添加和删除元素。

fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
print(fruits)  # 输出: ['apple', 'banana', 'cherry', 'orange']
del fruits[1]
print(fruits)  # 输出: ['apple', 'cherry', 'orange']

元组

元组与列表类似,但它们是不可变的,这意味着创建后它们的元素不能被修改。元组使用圆括号 () 定义。

my_tuple = (1, 2.5, "three")
print(my_tuple)  # 输出: (1, 2.5, 'three')
my_tuple[0] = 4  # TypeError: 'tuple' object does not support item assignment

字典

Python 中的字典是无序的键值对集合。它们使用花括号 {} 定义,每个键值对用冒号 : 分隔。

person = {
    "name": "John Doe",
    "age": 35,
    "city": "New York"
}
print(person)  # 输出: {'name': 'John Doe', 'age': 35, 'city': 'New York'}
print(person["age"])  # 输出: 35

运算符和表达式

算术运算符

Python 支持以下算术运算符: + (加法), - (减法), * (乘法), / (除法), // (整除), % (取模), 和 ** (指数).

x = 10
y = 3
print(x + y)  # 输出: 13
print(x - y)  # 输出: 7
print(x * y)  # 输出: 30
print(x / y)  # 输出: 3.3333333333333335
print(x // y)  # 输出: 3
print(x % y)  # 输出: 1
print(x ** y)  # 输出: 1000

比较运算符

Python 支持以下比较运算符: < (小于), > (大于), <= (小于或等于), >= (大于或等于), == (等于), 和 != (不等于)。

x = 10
y = 20
print(x < y)  # 输出: True
print(x > y)  # 输出: False
print(x <= 10)  # 输出: True
print(x >= y)  # 输出: False
print(x == 10)  # 输出: True
print(x != y)  # 输出: True

逻辑运算符

Python 支持以下逻辑运算符: and, or, 和 not

x = 10
y = 20
print(x < 15 and y > 15)  # 输出: True
print(x < 5 or y > 15)  # 输出: True
print(not(x < 5))  # 输出: True

位运算符

Python 也支持位运算符,它们对数字的个别位进行操作。这些包括 & (与), | (或), ^ (异或), ~ (非), << (左移), 和 >> (右移)。

x = 0b1010  # 二进制中的 10
y = 0b1100  # 二进制中的 12
print(x & y)  # 输出: 8 (0b1000)
print(x | y)  # 输出: 14 (0b1110)
print(x ^ y)  # 输出: 6 (0b0110)
print(~x)  # 输出: -11 (0b11111111111111111111111111110101)
print(x << 1)  # 输出: 20 (0b10100)
print(y >> 1)  # 输出: 6 (0b110)

控制流

条件语句

if-elif-else 语句用于根据特定条件执行不同的代码块。

x = 10
if x > 0:
    print("x 是正数")
elif x < 0:
    print("x 是负数")
else:
    print("x 是零")

循环

Python 有两种主要的循环结构: for 循环和 while 循环。

# For 循环
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)
 
# While 循环
count = 0
while count < 5:
    print(count)
    count += 1

Break 和 Continue

这. break 语句用于提前终止循环,而 continue 语句用于跳过当前迭代并移动到下一个迭代。

# Break 示例
for i in range(10):
    if i == 5:
        break
    print(i)
 
# Continue 示例
for i in range(10):
    if i % 2 == 0:
        continue
    print(i)

函数

在 Python 中,函数使用 def 关键字定义。它们可以接受参数并返回值。

def greet(name):
    print(f"你好, {name}!")
 
greet("Alice")  # 输出: 你好, Alice!
 
def add_numbers(a, b):
    return a + b
 
result = add_numbers(5, 3)
print(result)  # 输出: 8

函数还可以有默认参数值和可变长度参数。

def print_info(name, age=30):
    print(f"{name} 今年 {age} 岁。")
 
print_info("John")  # 输出: John 今年 30 岁。
print_info("Jane", 25)  # 输出: Jane 今年 25 岁。
 
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

模块和包

Python 的标准库提供了大量内置模块,您可以在程序中使用。您也可以创建自己的模块和包来组织代码。

import math
print(math.pi)  # 输出: 3.141592653589793
 
from math import sqrt
print(sqrt(16))  # 输出: 4.0
 
import my_module
my_module.my_function()

结论

在本教程中,您已经学习了 Python 的基础概念,包括变量、数据类型、运算符、控制流、函数和模块。有了这些知识,您可以开始构建自己的 Python 应用程序,并探索更高级的主题。记住,提高 Python 技能的最佳方式是定期练习和不断学习。

MoeNagy Dev.