每个数据科学家都应该知道的12个Python特性!

数据派THU

共 9500字,需浏览 19分钟

 · 2023-08-09

   
来源:大数据应用

本文约5700字,建议阅读11分钟

本文我们将深入探讨每个数据科学家都应该了解的12个Python特性。


图片来源:carbon

作为一名数据科学家,你对Python的强大功能并不陌生。从数据整理到机器学习,Python已成为数据科学事实上的语言。但是你是否利用了Python提供的所有特性?

在本文中,我们将深入探讨每个数据科学家都应该了解的12个Python特性。从推导式到数据类,这些特性将帮助你编写更高效、可读且可维护的代码。

01 推导

Python中的推导式是机器学习和数据科学任务的有用工具,因为它们允许以简洁且可读的方式创建复杂的数据结构。

列表推导式可用于生成数据列表,例如从一系列数字中创建平方值列表。嵌套列表推导式可用于平面化多维数组,这是数据科学中常见的预处理任务。


# list comprehension_list = [x**2 for x in range(1, 11)]
# nested list comprehension to flatten listmatrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat_list = [num # append to list            for row in matrix # outer loop            for num in row] # inner loop
print(_list)print(flat_list)[1, 4, 9, 16, 25, 36, 49, 64, 81, 100][1, 2, 3, 4, 5, 6, 7, 8, 9]


字典和集合推导式分别用于创建字典和数据集。例如,字典推导可用于在机器学习模型中创建特征名称及其相应值的字典。

生成器推导式对于处理大型数据集特别有用,因为它们动态生成值,而不是在内存中创建大型数据结构。这有助于提高性能并减少内存使用。


# dictionary comprehension_dict = {var:var ** 2 for var in range(1, 11) if var % 2 != 0}
# set comprehension# create a set of squares of numbers from 1 to 10_set = {x**2 for x in range(1, 11)}
# generator comprehension_gen = (x**2 for x in range(1, 11))
print(_dict)print(_set)print(list(g for g in _gen)){1: 1, 3: 9, 5: 25, 7: 49, 9: 81}{64, 1, 4, 36, 100, 9, 16, 49, 81, 25}[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]


02 枚举

enumerate是一个内置函数,允许迭代序列(例如列表或元组),同时跟踪每个元素的索引。

这在处理数据集时非常有用,因为它允许轻松访问和操作单个元素,同时跟踪其索引位置。

这里我们用enumerate迭代字符串列表,如果索引是偶数则打印出该值。



for idx, value in enumerate(["a", "b", "c", "d"]):    if idx % 2 == 0:        print(value)ac


03 Zip

zip是一个内置函数,允许并行迭代多个序列(例如列表或元组)。

下面我们使用zip同时迭代两个列表x和y并对其相应的元素执行操作。


x = [1, 2, 3, 4]y = [5, 6, 7, 8]
# iterate over both arrays simultaneouslyfor a, b in zip(x, y):    print(a, b, a + b, a * b)1 5 6 52 6 8 123 7 10 214 8 12 32

在本例中,它打印出和中每个元素的值x和y,它们的总和以及它们的乘积。

04 生成器

Python中的生成器是一种可迭代类型,它允许动态生成一系列值,而不是一次生成所有值并将它们存储在内存中。

这使得它们对于处理无法放入内存的大型数据集非常有用,因为数据是小块或批量处理的,而不是一次性处理的。

下面我们使用生成器函数来生成Fibonacci数列中的第一个数字n。该yield关键字用于一次生成序列中的每个值,而不是一次生成整个序列。


def fib_gen(n):    a, b = 0, 1    for _ in range(n):        yield a        a, b = b, a + b

res = fib_gen(10)print(list(r for r in res))[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]


05 Lambda函数

lambda是用于创建匿名函数的关键字,匿名函数是没有名称并且可以在一行代码中定义的函数。

它们对于动态定义自定义函数以进行特征工程、数据预处理或模型评估非常有用。

下面我们lambda创建一个简单的函数来从数字列表中过滤偶数。


numbers = range(10)even_numbers = list(filter(lambda x: x % 2 == 0, numbers))print(even_numbers)[0, 2, 4, 6, 8]

这是在Pandas中使用lambda函数的另一个代码片段。


import pandas as pd
data = {    "sales_person": ["Alice", "Bob", "Charlie", "David"],    "sale_amount": [100, 200, 300, 400],}df = pd.DataFrame(data)
threshold = 250df["above_threshold"] = df["sale_amount"].apply(    lambda x: True if x >= threshold else False)dfsales_person   sale_amount   above_threshold0   Alice   100   False1   Bob   200   False2   Charlie   300   True3   David   400   True


06 映射、过滤、归约

函数map、filter和reduce是三个用于操作和转换数据的内置函数。

map用于将函数应用于可迭代的每个元素,filter用于根据条件从可迭代中选择元素,reduce用于将函数应用于迭代中的成对元素以产生单个结果。

下面是一个综合应用三个函数的例子,计算偶数的平方和。


numbers = range(10)
# Use map(), filter(), and reduce() to preprocess and aggregate the list of numberseven_numbers = filter(lambda x: x % 2 == 0, numbers)squares = map(lambda x: x**2, even_numbers)sum_of_squares = reduce(lambda x, y: x + y, squares)

print(f"Sum of the squares of even numbers: {sum_of_squares}")Sum of the squares of even numbers: 120


07 any和all

any和all是内置函数,允许检查可迭代中的任何或所有元素是否满足特定条件。

any和all可用于检查数据集或数据集子集是否满足某些条件。例如,它们可用于检查列中是否缺少任何值,或者列中的所有值是否在特定范围内。

下面是检查是否存在偶数值和所有奇数值的简单示例。


data = [1, 3, 5, 7]print(any(x % 2 == 0 for x in data))print(all(x % 2 == 1 for x in data))FalseTrue


08 next

next用于从迭代器中检索下一个项目。迭代器是可以迭代(循环)的对象,例如列表、元组、集合或字典。

next在数据科学中通常用于迭代迭代器或生成器对象。它允许用户从可迭代中检索下一个项目,并且对于处理大型数据集或流数据非常有用。

下面,我们定义一个生成器random_numbers(),生成0到1之间的随机数。然后,我们使用next()函数查找生成器中第一个大于0.9的数字。


import random 
def random_numbers():    while True:        yield random.random()
# Use next() to find the first number greater than 0.9num = next(x for x in random_numbers() if x > 0.9)
print(f"First number greater than 0.9: {num}")First number greater than 0.9: 0.9444805819267413


09 默认字典


defaultdict是内置类的子类dict,允许为缺失的键提供默认值。


defaultdict对于处理丢失或不完整的数据非常有用,例如在处理稀疏

矩阵或特征向量时。它还可用于计算分类变量的频率。


一个例子是计算列表中项目的出现次数。如果传入default_factory的参数为int,一开始初始化键对应的值都为0。


from collections import defaultdict
count = defaultdict(int)for item in ['a', 'b', 'a', 'c', 'b', 'a']:    count[item] += 1
countdefaultdict(int, {'a': 3, 'b': 2, 'c': 1})


10 partial

partial是functools模块中的一个函数,它允许从预先填充了某些参数的现有函数创建新函数。

partial对于创建带有预先填充的特定参数或参数的自定义函数或数据转换非常有用。这有助于减少定义和调用函数时所需的样板代码量。

在这里,我们使用partial现有函数add创建一个新函数increment,并将其参数之一固定为值1。

调用increment(1)本质上就是调用add(1, 1)


from functools import partial
def add(x, y):    return x + y
increment = partial(add, 1)increment(1)2


11 lru_cache


lru_cache是functools模块中的一个修饰函数,它允许使用有限大小的缓存来缓存函数的结果。


lru_cache对于优化计算成本较高的函数或可能使用相同参数多次调用的模型训练过程非常有用。


缓存可以帮助加快函数的执行速度并降低总体计算成本。


这是一个使用缓存有效计算Fibonacci numbers(https://en.wikipedia.org/wiki/Fibonacci_number)的示例(在计算机科学中称为记忆)


rom functools import lru_cache
@lru_cache(maxsize=None)def fibonacci(n):    if n <= 1:        return n    return fibonacci(n - 1) + fibonacci(n - 2)
fibonacci(1e3)4.346655768693743e+208


12 数据类

@dataclass修饰器根据定义的属性自动类生成几个特殊方法,例如__init__,__repr__,和__eq__。

这有助于减少定义类时所需的样板代码量。dataclass对象可以表示数据点、特征向量或模型参数等。

在此示例中,dataclass用于定义Person具有三个属性的简单类:name、age和city。


from dataclasses import dataclass
@dataclassclass Person:    name: str    age: int    city: str
p = Person("Alice", 30, "New York")print(p)Person(name='Alice', age=30, city='New York')



原文链接:
https://medium.com/bitgrit-data-science-publication/12-python-features-every-data-scientist-should-know-1d233dbaab0c

编辑:王菁

浏览 1890
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报