54、Python实用技巧与数据处理

Python实用技巧与数据处理

1. 开始使用Python

在完成Python的基础设置后,就可以在计算机上运行Python代码了。如果你是Python新手,接下来需要学习一些语言特性。Python是最简单、最易学习的编程语言之一,网上有许多优秀的资源和书籍可帮助你学习Python编程基础,python.org是个很好的起点。

2. Python中的数字与数学运算

Python和大多数语言一样,内置了对基本数学运算的支持。下面为你介绍一些常见的运算操作。

2.1 基本算术运算符

Python中的基本算术运算符包括 + - * / 。需要注意的是,在Python 3中进行整数除法时,可能会得到小数结果,例如:

>>> 7/2
3.5

而在Python 2中,上述运算结果为2,即直接舍弃余数的整数除法结果。若需要获取余数,可以使用 % 运算符,也就是取模运算符。例如:

>>> 13 % 5
3

这表明13除以5的余数是3(即13 = 2 × 5 + 3)。取模运算符同样适用于浮点数,例如可以用它来获取一个数的小数部分:

>>> 3.75 % 1
0.75

除了上述四个基本运算符外, ** 运算符用于计算幂次方。例如:

>>> 2 ** 3
8
>>> 4 ** 2
16

在Python中进行浮点数运算时,结果可能并不精确。例如:

>>> 1000.1 - 1000.0
0.10000000000002274

虽然这个结果与正确答案的误差在万亿分之一以内,不会引发问题,但乍一看可能会让人觉得结果有误。例如:

>>> (1000.1 - 1000.0) - 0.1
2.273181642920008e-14

这个长数字采用科学记数法表示,约为2.27 × 10⁻¹⁴,实际上非常接近零。

2.2 math模块

Python的 math 模块提供了更多有用的数学常量和函数。使用时,需要从该模块中导入所需的对象。例如,导入圆周率 pi

from math import pi
>>> pi
3.141592653589793
>>> tau = 2 * pi
>>> tau
6.283185307179586

也可以直接导入 math 模块,然后按需访问其中的值:

>>> import math
>>> math.pi
3.141592653589793
>>> math.e
2.718281828459045

math 模块还包含一些重要的函数,如平方根函数 sqrt 、三角函数 cos sin 、指数函数 exp 以及自然对数函数 log 等。调用这些函数时,需在括号内提供输入值:

>>> math.sqrt(25)
5.0
>>> math.sin(pi/2)
1.0
>>> math.cos(pi/3)
0.5000000000000001
>>> math.exp(2)
7.38905609893065
>>> math.log(math.exp(2))
2.0

需要注意的是, math.exp(x) 等同于 math.e ** x ,而 math.log 函数则是 math.exp 函数的逆运算。三角函数在相关章节有详细介绍。

2.3 随机数

有时我们需要选择一些任意数字来测试计算结果,这时可以使用Python的随机数生成器。这些生成器位于 random 模块中,使用前需先导入:

import random

该模块中的 randint 函数可返回指定范围内随机选取的整数,例如:

>>> random.randint(0,10)
7
>>> random.randint(0,10)
1

random.uniform 函数用于生成指定区间内的随机浮点数。例如:

>>> random.uniform(7.5, 9.5)
8.200084576283352

“uniform”表示该区间内的每个子区间被选中的概率相同。与之相反,如果随机选取人的年龄,得到的随机数分布是不均匀的,例如10 - 20岁的人数可能会比100 - 110岁的人数多很多。

3. Python中的数据集合

在Python中,有多种方式来处理数据集合,下面为你详细介绍。

3.1 列表

列表是Python中最基本的数据集合。创建列表时,只需将一些值用方括号括起来,并用逗号分隔。例如:

months = ["January", "February", "March"]

可以通过索引(从0开始计数)来访问列表中的元素。例如:

>>> months[0]
'January'
>>> months[1]
'February'
>>> months[2]
'March'

若尝试访问超出有效索引范围的元素,会引发错误。例如, months[3] months[17] 是不存在的。在某些情况下,可以使用取模运算符来确保索引的有效性,例如对于任意整数 n months[n % 3] 总是有效的,因为 n % 3 的结果只能是0、1或2。
还可以通过解包的方式来访问列表元素。如果确定列表中有三个元素,可以这样操作:

j, f, m = months
>>> j
'January'
>>> f
'February'
>>> m
'March'

列表的另一个基本操作是拼接,使用 + 运算符可以将两个列表按顺序合并成一个更大的列表。例如:

>>> [1,2,3] + [4,5,6]
[1, 2, 3, 4, 5, 6]

Python还支持列表切片操作,用于提取列表中两个索引之间的所有元素。例如:

>>> months[1:3]
['February', 'March']

上述代码表示从索引1开始,到索引3(不包含)结束的切片。再看一个更清晰的例子:

>>> nums = [0,1,2,3,4,5,6,7,8,9,10]
>>> nums[2:5]
[2, 3, 4]

可以使用 len 函数来计算列表的长度:

>>> len(months)
3
>>> len(nums)
11

由于列表索引从0开始,因此最后一个元素的索引为列表长度减1。可以通过以下两种方式获取列表的最后一个元素:

>>> nums[len(nums)-1]
10
>>> nums[-1]
10

nums[-2] 则返回倒数第二个元素,即9。正索引、负索引和切片可以有多种组合方式。例如:

>>> nums[1:]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> nums[3:-1]
[3, 4, 5, 6, 7, 8, 9]

需要注意的是,不要将列表切片语法(涉及两个索引)与从嵌套列表中获取元素(也涉及两个索引)混淆。例如:

list_of_lists = [[1,2,3],[4,5,6],[7,8,9]]
>>> list_of_lists[2][1]
8

在处理列表时,经常需要遍历列表中的每个元素。在Python中,最简便的方法是使用 for 循环。例如:

>>> for x in months:
>>>     print('Month: ' + x)
Month: January
Month: February
Month: March

也可以通过创建一个空列表,然后使用 append 方法逐步添加元素来构建新列表。例如:

squares = []
for n in nums:
    squares.append(n * n)
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Python还提供了列表推导式这一特殊语法,用于迭代构建列表。它本质上是一种特殊的 for 循环,用方括号括起来,表示在迭代的每一步添加列表元素。列表推导式的语法类似于自然语言,易于理解。例如:

>>> [x * x for x in nums]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

列表推导式还可以同时遍历多个源列表。例如:

>>> years = [2018,2019,2020]
>>> [m + " " + str(y) for y in years for m in months]
['January 2018',
 'February 2018',
 'March 2018',
 'January 2019',
 'February 2019',
 'March 2019',
 'January 2020',
 'February 2020',
 'March 2020']

通过嵌套列表推导式,可以构建列表的列表:

>>> [[m + " " + str(y) for y in years] for m in months]
[['January 2018', 'January 2019', 'January 2020'],
 ['February 2018', 'February 2019', 'February 2020'],
 ['March 2018', 'March 2019', 'March 2020']]
3.2 其他可迭代对象

在Python(尤其是Python 3.x)中,还有一些其他类型的集合,其中一些被称为可迭代对象,因为可以像遍历列表一样遍历它们。最常用的可迭代对象之一是 range ,用于构建有序的数字序列。例如:

>>> range(5,10)
range(5, 10)

虽然直接计算 range(5,10) 的结果看起来并不直观,但可以像遍历列表一样遍历它:

>>> for i in range(5,10):
>>>    print(i)
5
6
7
8
9

range 不是列表,这使得我们可以使用非常大的范围而无需一次性迭代所有元素。例如, range(0,1000000000) 定义了一个包含十亿个数字的范围,但实际上并不存储十亿个数字,只是存储了在迭代过程中生成这些数字的指令。如果需要将 range 转换为列表,可以使用 list 函数:

>>> list(range(0,10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

range 函数的部分参数是可选的。如果只提供一个输入,它会自动从0开始,直到该输入数字;如果提供第三个参数,则表示步长。例如:

>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(0,10,3))
[0, 3, 6, 9]

zip 函数也是一个返回特殊可迭代对象的例子。它接受两个长度相同的可迭代对象,并返回一个由对应元素组成的可迭代对象:

>>> z = zip([1,2,3],["a","b","c"])
>>> z
<zip at 0x15fa8104bc8>
>>> list(z)
[(1, 'a'), (2, 'b'), (3, 'c')]

需要注意的是,并非所有可迭代对象都支持索引操作。例如, z[2] 是无效的,需要先将其转换为列表,如 list(z)[2] range 支持索引操作,例如 range(5,10)[3] 返回8。另外,一旦遍历了 zip 对象,它就不再存在了,因此如果需要重复使用,最好立即将其转换为列表。

下面是一个简单的流程图,展示了可迭代对象的使用流程:

graph TD;
    A[定义可迭代对象] --> B{是否为range};
    B -- 是 --> C[可直接遍历或转换为列表];
    B -- 否 --> D{是否为zip};
    D -- 是 --> E[转换为列表后使用];
    D -- 否 --> F[按常规方式处理];
3.3 生成器

Python的生成器提供了一种创建可迭代对象的方式,它不会一次性存储所有值,而是存储生成值的指令。这使得我们可以定义大型甚至无限的序列,而无需将它们全部存储在内存中。生成器的基本创建方式类似于函数,但使用 yield 关键字代替 return 。生成器可以产生多个值,而函数最多返回一次就结束了。
例如,以下生成器表示从0开始的无限整数序列:

def count():
    x = 0
    while True:
        yield x
        x += 1

虽然这表示一个无限序列,但调用 count() 不会导致计算机崩溃,它只是返回一个生成器对象:

>>> count()
<generator object count at 0x0000015FA80EC750>

for x in count() 这样的循环是有效的,但会无限运行。可以使用 break 语句来终止循环:

for x in count():
    if x > 1000:
        break
    else:
        print(x)

下面是一个更实用的生成器,它类似于 range 函数,只生成有限个值:

def count(a,b):
    x = a
    while x < b:
        yield x
        x += 1

count(10,20) 的结果是一个类似于 range(10,20) 的生成器,可以在列表推导式中使用:

>>> count(10,20)
<generator object count at 0x0000015FA80EC9A8>
>>> [x for x in count(10,20)]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

可以通过将列表推导式的方括号替换为圆括号来创建生成器表达式。例如:

(x*x for x in range(0,10))

它的行为与以下生成器相同:

def squares():
    for x in range(0,10):
        yield x*x

当生成器是有限的时,可以使用 list 函数将其安全地转换为列表:

>>> list(squares())
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3.4 元组

元组是一种类似于列表的可迭代对象,但它是不可变的,即创建后不能修改。这意味着元组没有 append 方法,一旦创建,其长度就固定不变。元组适用于存储成对或成组的数据。创建元组的方式与列表类似,只是使用括号(或不使用任何括号)代替方括号:

>>> (1,2)
(1, 2)
>>> ("a","b","c")
('a', 'b', 'c')
>>> 1,2,3,4,5
(1, 2, 3, 4, 5)

在前面提到的 zip 函数返回的结果中,每个元素实际上就是一个元组。在某种意义上,元组是Python中的默认集合。例如:

a = 1,2,3,4,5

此时 a 会自动被解释为一个包含这些数字的元组。同样,如果函数以 return a,b 结束,实际返回的是元组 (a,b)
由于元组通常较短,通常不需要遍历它们。虽然没有元组推导式,但可以在其他推导式中遍历元组,并使用内置的 tuple 函数将结果转换回元组。例如:

>>> a = 1,2,3,4,5
>>> tuple(x + 10 for x in a)
(11, 12, 13, 14, 15)
3.5 集合

Python集合中的每个元素必须是唯一的,并且不记录元素的顺序。在某些情况下,将列表转换为集合是确保列表中没有重复值的快速方法。可以使用 set 函数将可迭代对象转换为集合:

>>> dups = [1,2,3,3,3,3,4,5,6,6,6,6,7,8,9,9,9]
>>> set(dups)
{1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> list(set(dups))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Python集合使用花括号表示,这与数学中的集合表示方法相同。可以直接使用花括号定义集合。由于集合不考虑顺序,只要两个集合的元素完全相同,它们就相等:

>>> set([1,1,2,2,3]) == {3,2,1}
True

以下是一个表格,总结了各种数据集合的特点:
| 数据集合类型 | 是否可变 | 是否有序 | 是否允许重复元素 | 常用操作 |
| ---- | ---- | ---- | ---- | ---- |
| 列表 | 是 | 是 | 是 | 索引、切片、拼接、遍历、列表推导式 |
| 元组 | 否 | 是 | 是 | 索引、解包、遍历 |
| 集合 | 是 | 否 | 否 | 去重、判断元素是否存在 |
| 生成器 | 无 | 无 | 无 | 迭代生成值 |
| range | 无 | 是 | 无 | 生成连续整数序列 |
| zip | 无 | 是 | 无 | 组合多个可迭代对象 |

通过以上介绍,你对Python中的数字运算、数据集合等方面有了更深入的了解。在实际编程中,可以根据具体需求选择合适的数据结构和操作方法,以提高代码的效率和可读性。

Python实用技巧与数据处理

4. NumPy数组

除了Python内置的数据集合外,NumPy数组也是一种常用的数据集合,它来自NumPy包,是Python中事实上的标准数值计算库。NumPy数组在处理大规模数值数据时具有高效性,并且提供了许多方便的数学运算和操作。

以下是一个简单的NumPy数组创建示例:

import numpy as np

# 创建一个一维数组
arr1 = np.array([1, 2, 3, 4, 5])
print("一维数组:", arr1)

# 创建一个二维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print("二维数组:", arr2)

NumPy数组的索引和切片操作与列表类似,但更加灵活和强大。例如:

# 一维数组索引
print("一维数组索引:", arr1[2])

# 二维数组索引
print("二维数组索引:", arr2[1, 2])

# 一维数组切片
print("一维数组切片:", arr1[1:4])

# 二维数组切片
print("二维数组切片:", arr2[:, 1:])

NumPy数组还支持各种数学运算,这些运算可以直接应用于整个数组,而无需使用循环。例如:

# 数组加法
arr3 = arr1 + 10
print("数组加法:", arr3)

# 数组乘法
arr4 = arr1 * 2
print("数组乘法:", arr4)

# 数组之间的运算
arr5 = arr1 + arr3
print("数组之间的加法:", arr5)

NumPy还提供了许多用于数组操作的函数,如求和、求平均值、求最大值等。例如:

# 数组求和
sum_arr = np.sum(arr1)
print("数组求和:", sum_arr)

# 数组求平均值
mean_arr = np.mean(arr1)
print("数组求平均值:", mean_arr)

# 数组求最大值
max_arr = np.max(arr1)
print("数组求最大值:", max_arr)

下面是一个流程图,展示了使用NumPy数组进行数据处理的基本流程:

graph TD;
    A[导入NumPy库] --> B[创建NumPy数组];
    B --> C{选择操作类型};
    C -- 索引/切片 --> D[进行索引或切片操作];
    C -- 数学运算 --> E[进行数组数学运算];
    C -- 统计计算 --> F[进行统计计算];
    D --> G[输出结果];
    E --> G;
    F --> G;
5. 综合应用示例

为了更好地理解和应用上述Python知识,下面给出一个综合应用示例。假设我们要模拟一个简单的抽奖活动,参与者的编号从1到100,我们需要随机抽取5名幸运参与者。

import random

# 生成参与者编号列表
participants = list(range(1, 101))

# 随机抽取5名幸运参与者
lucky_participants = random.sample(participants, 5)

print("幸运参与者编号:", lucky_participants)

在这个示例中,我们首先使用 range 函数生成了一个从1到100的参与者编号列表,然后使用 random.sample 函数从这个列表中随机抽取了5个不重复的元素作为幸运参与者的编号。

6. 总结与建议

通过前面的介绍,我们对Python中的数字运算、数据集合(包括列表、元组、集合、生成器、range、zip和NumPy数组)等方面有了全面的了解。在实际编程中,我们可以根据不同的需求选择合适的数据结构和操作方法。

以下是一些总结和建议:
- 选择合适的数据结构
- 如果需要频繁修改元素,列表是一个不错的选择。
- 如果数据是不可变的,并且需要保持顺序,元组更合适。
- 如果需要去重,集合是首选。
- 对于大规模数值计算,NumPy数组具有高效性。
- 如果需要生成大型或无限序列,生成器是一个很好的解决方案。
- 合理使用数学运算和函数
- 利用Python内置的数学运算符和 math 模块进行基本数学运算。
- 使用 random 模块生成随机数进行测试或模拟。
- 借助NumPy库的函数进行高效的数值计算和统计分析。
- 提高代码可读性和效率
- 使用列表推导式、生成器表达式等简洁的语法来构建列表和生成器。
- 避免不必要的循环,利用数组的向量化运算提高代码效率。

通过不断练习和实践,你将更加熟练地掌握这些Python技巧和数据处理方法,从而编写出更加高效、简洁和易读的代码。

希望这些内容对你学习和使用Python有所帮助,祝你在编程的道路上取得更多的进步!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值