超越NumPy和Pandas:三个鲜为人知的Python库

2023年 9月 8日 28.3k 0

Python是世界上使用最广泛的编程语言之一,并为开发人员提供了大量的库。

然而,当涉及到数据处理和科学计算时,用户通常会想到诸如Numpy、Pandas或SciPy等库。

在本文中,将介绍3个你可能感兴趣的Python库。

1.Dask

Dask简介

Dask是一个灵活的并行计算库,可实现大规模数据处理的分布式计算和并行计算。

那么,为什么用户要使用Dask呢?正如他们在其网站上所说的:

【Dask】:https://www.dask.org/

Python已经发展成为数据分析和通用编程中的主流语言。这种增长得益于像NumPy、Pandas和scikit-learn等计算库。然而,这些包并不适用于超越单台机器的规模。当数据集超过内存时,Dask被开发出来原生地扩展这些包及其周边生态系统,以适应多核机器和分布式集群。

因此,正如他们所说,Dask的一个常见用途是:

【链接】:https://docs.dask.org/en/latest/dataframe.html

当需要像使用Pandas一样常用时,使用Dask DataFrame,通常是因为Pandas在处理数据量或计算速度方面存在问题:

  • 处理大型数据集,即使这些数据集无法容纳在内存中
  • 通过使用多个内核加速长时间计算
  • 对使用标准Pandas操作的大型数据集进行分布式计算,例如groupby、join和时间序列计算

因此,当需要处理巨大的Pandas数据帧时,Dask是一个不错的选择。这是因为Dask可以:

允许用户在笔记本电脑上处理100GB以上的数据集,或者在工作站上处理1TB以上的数据集。

这是一个相当了不起的结果。

在幕后发生的情况是:

Dask DataFrames协调许多按索引排列的Pandas DataFrames/Series。Dask DataFrame以行为单位进行分区,通过索引值对行进行分组,以提高效率。这些Pandas对象可以存在于磁盘上或其他机器上。

因此,有类似的如下情况:

图片Dask和Pandas数据帧的区别。

运行中的Dask的一些功能展示

首先,需要安装Dask。可以通过pip或conda进行安装,如下所示:

$ pip install dask[complete]

or

$ conda install dask

功能一:打开 csv 文件

可以展示Dask的第一个功能,即如何打开CSV文件。可以这样做,如下所示:

import dask.dataframe as dd

# 使用Dask加载大型CSV文件
df_dask = dd.read_csv('my_very_large_dataset.csv')

# 在Dask DataFrame上执行操作
mean_value_dask = df_dask['column_name'].mean().compute()

因此,正如在代码中看到的,本文使用Dask的方式与Pandas非常相似。尤其是:

  • 使用read_csv()方法与Pandas完全相同
  • 截取列的方式与Pandas完全相同。事实上,如果有一个名为df的Pandas数据框架,我们会这样截取一列:df['column_name']。
  • 将mean()方法应用于截取的列,这与Pandas类似,但这里还需要添加compute()方法。

此外,即使打开CSV文件的方法与Pandas相同,Dask也能毫不费力地处理超过单台机器内存容量的大型数据集。

这意味着,除了在Pandas中无法打开大型数据帧,而在Dask中可以打开之外,无法看到任何实际的差异。

功能二:扩展机器学习工作流程

可以使用Dask创建一个具有大量样本的分类数据集。然后可以将其分割为训练集和测试集,使用机器学习模型拟合训练集,并计算测试集的预测结果。

可以这样做,如下所示:

import dask_ml.datasets as dask_datasets
from dask_ml.linear_model import LogisticRegression
from dask_ml.model_selection import train_test_split

# 使用Dask加载分类数据集
X, y = dask_datasets.make_classification(n_samples=100000, chunks=1000)

# 将数据分割为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y)

# 并行训练逻辑回归模型
model = LogisticRegression()
model.fit(X_train, y_train)

# 对测试集进行预测
y_pred = model.predict(X_test).compute()

该示例强调了Dask处理大规模数据集的能力,即使是在机器学习问题的情况下,也可以通过在多个内核之间分布计算来实现。

具体而言,可以使用dask_datasets.make_classification()方法为分类问题创建一个“Dask dataset” ,并且可以指定样本数量和块大小(甚至是非常巨大的数量)。

与之前类似,预测结果是通过compute()方法获得的。

# 注意:

# 在这种情况下,可能需要安装模块`dask_ml`。

# 可以按以下方式进行安装:

$ pip install dask_ml

功能三:高效图像处理

Dask所利用的并行处理能力也可以应用于图像处理。

特别是可以打开多个图像,调整其大小,并保存调整后的图像。可以按以下方式操作:

import dask.array as da
import dask_image.imread
from PIL import Image

# 使用Dask加载图像集合
images = dask_image.imread.imread('image*.jpg')

# 并行调整图像大小
resized_images = da.stack([da.resize(image, (300, 300)) for image in images])

# 计算结果
result = resized_images.compute()

# 保存调整后的图像
for i, image in enumerate(result):
    resized_image = Image.fromarray(image)
    resized_image.save(f'resized_image_{i}.jpg')

因此,下面是整个过程:

  • 使用dask_image.imread.imread("image*.jpg")方法打开当前文件夹中的所有".jpg"图像(或者可以指定一个文件夹)。
  • 使用da.stack()方法和列表推导式将所有图像的大小调整为300x300。
  • 使用compute()方法计算结果,就像之前一样。
  • 使用for循环保存所有调整过大小的图像。
  • 2.SymPy

    Sympy简介

    如果需要进行数学计算,并希望使用Python进行操作,可以尝试使用SymPy。

    正如他们在网站上所写的介绍那样,Sympy是:

    【Sympy】:https://www.sympy.org/en/index.html

    一个用于符号数学的Python库。它旨在成为一个功能齐全的计算机代数系统(CAS),同时保持代码尽可能简单,以便易于理解和扩展。SymPy完全使用Python编写。

    但是为什么要使用SymPy?他们提到:

    SymPy具有以下特点:

    • 免费:SymPy采用BSD许可证,既具有言论自由,也免费。
    • 基于Python:SymPy完全使用Python编写,并使用Python作为其语言。
    • 轻量级:SymPy仅依赖于mpmath,这是一个用于任意浮点数算术的纯Python库,因此易于使用。
    • 作为库存在:除了作为交互工具使用外,SymPy还可以嵌入到其他应用程序中,并使用自定义函数进行扩展。

    因此,它基本上具备了所有Python爱好者所喜爱的特性!

    现在来查看一下它的部分功能。

    SymPy的一些功能

    首先,需要安装它:

    $ pip install sympy
    请注意:
    
    如果写成`$ pip install simpy`,将安装另一个(完全不同的!)库。
    
    因此,第二个字母是"y",而不是"i"。

    功能一:解代数方程

    如果需要解代数方程,可以这样使用SymPy:

    from sympy import symbols, Eq, solve
    
    # 定义符号
    x, y = symbols('x y')
    
    # 定义方程
    equation = Eq(x**2 + y**2, 25)
    
    # 解方程
    solutions = solve(equation, (x, y))
    
    # 打印解
    print(solutions)
    
    
    >>>
    
    
    [(-sqrt(25 - y**2), y), (sqrt(25 - y**2), y)]

    所以,这就是整个过程:

  • 使用symbols()方法定义方程的符号。
  • 使用Eq方法编写代数方程。
  • 使用solve()方法解方程。
  • 正如上述所看到的,SymPy是一个非常易读和用户友好的Python库。

    功能二:计算导数

    计算导数是在分析数据时可能需要的另一个数学任务,原因有很多。通常情况下,可能因为各种原因需要进行计算,而SymPy真正简化了这个过程。实际上,可以这样做,如下所示:

    from sympy import symbols, diff
    
    # 定义符号
    x = symbols('x')
    
    # 定义函数
    f = x**3 + 2*x**2 + 3*x + 4
    
    # 计算导数
    derivative = diff(f, x)
    
    # 打印导数
    print(derivative)
    
    >>>
    
    3*x**2 + 4*x + 3

    因此,正如上述所看到的,这个过程非常简单和容易自解释:

  • 使用symbols()方法定义要求导的函数的符号。
  • 定义函数。
  • 使用diff()计算导数,并指定函数和要计算导数的符号(这是一个绝对导数,但在具有x和y变量的函数的情况下,甚至也可以进行计算偏导数)。
  • 如果进行测试,就会发现结果在2或3秒钟内就会出现。因此,它的速度也相当快。

    功能三:计算积分

    当然,如果SymPy可以计算导数,它也可以计算积分。接下来尝试做一下:

    from sympy import symbols, integrate, sin
    
    # 定义符号
    x = symbols('x')
    
    # 执行符号积分
    integral = integrate(sin(x), x)
    
    # 打印积分
    print(integral)
    
    >>>
    
    -cos(x)

    所以,本文在这里使用integrate()方法,指定要积分的函数和积分变量。

    3.Xarray

    Xarray简介

    Xarray是一个扩展了NumPy特性和功能的Python库,使用户能够使用带有标签的数组和数据集进行工作。

    事实上,正如他们在官网上所说的那样:

    【Xarray】:https://docs.xarray.dev/en/stable/

    Xarray使得在Python中处理带有标签的多维数组变得简单、高效和有趣!

    还有:

    【链接】:https://docs.xarray.dev/en/stable/getting-started-guide/why-xarray.html

    Xarray在类似于NumPy的原始多维数组之上引入了维度、坐标和属性形式的标签,这使得开发者的体验更加直观、简洁,减少了错误的发生。

    换句话说,它通过向数组维度添加标签或坐标来扩展NumPy数组的功能。这些标签提供了元数据,可以对多维数据进行更高级的分析和操作。

    例如,在NumPy中,使用基于整数的索引访问数组。

    而在Xarray中,每个维度都可以关联一个标签,这样就可以根据有意义的名称更容易地理解和操作数据。

    例如,在Xarray中,用户可以使用arr.sel(x=0, y=1, z=2)来访问数据,其中x、y和z是维度的标签,而不是使用arr[0, 1, 2]来访问数据。

    这使得代码更加易读!

    接下来查看一些Xarray的功能。

    一些Xarray的功能

    像往常一样,首先要安装它:

    $ pip install xarray

    功能一:使用标注坐标

    假设用户想创建与温度相关的一些数据,并且想将它们标记为纬度和经度等坐标。可以这样做:

    import xarray as xr
    import numpy as np
    
    # 创建温度数据
    temperature = np.random.rand(100, 100) * 20 + 10
    
    # 创建经纬度坐标数组
    latitudes = np.linspace(-90, 90, 100)
    longitudes = np.linspace(-180, 180, 100)
    
    # 创建带有标注坐标的Xarray数据数组
    da = xr.DataArray(
        temperature,
        dims=['latitude', 'longitude'],
        coords={'latitude': latitudes, 'longitude': longitudes}
    )
    
    # 使用标注坐标访问数据
    subset = da.sel(latitude=slice(-45, 45), lnotallow=slice(-90, 0))

    如果打印出来,就会得到

    # 打印数据
    print(subset)
    
    >>>
    
    array([[13.45064786, 29.15218061, 14.77363206, ..., 12.00262833,
            16.42712411, 15.61353963],
           [23.47498117, 20.25554247, 14.44056286, ..., 19.04096482,
            15.60398491, 24.69535367],
           [25.48971105, 20.64944534, 21.2263141 , ..., 25.80933737,
            16.72629302, 29.48307134],
           ...,
           [10.19615833, 17.106716  , 10.79594252, ..., 29.6897709 ,
            20.68549602, 29.4015482 ],
           [26.54253304, 14.21939699, 11.085207  , ..., 15.56702191,
            19.64285595, 18.03809074],
           [26.50676351, 15.21217526, 23.63645069, ..., 17.22512125,
            13.96942377, 13.93766583]])
    Coordinates:
      * latitude   (latitude) float64 -44.55 -42.73 -40.91 ... 40.91 42.73 44.55
      * longitude  (longitude) float64 -89.09 -85.45 -81.82 ... -9.091 -5.455 -1.818

    所以,接下来逐步了解这个过程:

  • 将温度值创建为一个NumPy数组。
  • 将纬度和经度值定义为NumPy数组。
  • 使用DataArray()方法将所有数据存储在一个Xarray数组中。
  • 使用sel()方法选择了一个经纬度子集,该方法为子集选择了我们想要的值。
  • 这样得到的结果也很容易阅读,因此标签在很多情况下非常有帮助。

    功能二:处理缺失数据

    假设用户正在收集与一年中与温度相关的数据。并且想知道数组中是否有空值。如下是用户可以这样做的方法:

    import xarray as xr
    import numpy as np
    import pandas as pd
    
    # 创建有缺失值的温度数据
    temperature = np.random.rand(365, 50, 50) * 20 + 10
    temperature[0:10, :, :] = np.nan  # Set the first 10 days as missing values
    
    # 创建时间、纬度和经度坐标数组
    times = pd.date_range('2023-01-01', periods=365, freq='D')
    latitudes = np.linspace(-90, 90, 50)
    longitudes = np.linspace(-180, 180, 50)
    
    # 创建带有缺失值的Xarray数据数组
    da = xr.DataArray(
        temperature,
        dims=['time', 'latitude', 'longitude'],
        coords={'time': times, 'latitude': latitudes, 'longitude': longitudes}
    )
    
    # 沿时间维度计算缺失值的数量
    missing_count = da.isnull().sum(dim='time')
    
    # 打印缺失值
    print(missing_count)
    
    >>>
    
    
    array([[10, 10, 10, ..., 10, 10, 10],
           [10, 10, 10, ..., 10, 10, 10],
           [10, 10, 10, ..., 10, 10, 10],
           ...,
           [10, 10, 10, ..., 10, 10, 10],
           [10, 10, 10, ..., 10, 10, 10],
           [10, 10, 10, ..., 10, 10, 10]])
    Coordinates:
      * latitude   (latitude) float64 -90.0 -86.33 -82.65 ... 82.65 86.33 90.0
      * longitude  (longitude) float64 -180.0 -172.7 -165.3 ... 165.3 172.7 180.0

    这样,我们就得到了10个空数值。

    此外,如果我们仔细查看代码,就会发现我们可以将Pandas的方法应用到Xarray中,比如isnull.sum(),在本例中,它可以计算缺失值的总数。

    功能三:处理和分析多维数据

    当我们可以给数组贴标签时,处理和分析多维数据的诱惑就会很大。那么,接下来跟随本文进行尝试。

    例如,假设用户仍在收集与特定纬度和经度相关的温度数据。

    我们可能想要计算温度的平均值、最大值和中值。可以进行如下操作:

    import xarray as xr
    import numpy as np
    import pandas as pd
    
    # 创建合成温度数据
    temperature = np.random.rand(365, 50, 50) * 20 + 10
    
    # 创建时间、纬度和经度坐标数组
    times = pd.date_range('2023-01-01', periods=365, freq='D')
    latitudes = np.linspace(-90, 90, 50)
    longitudes = np.linspace(-180, 180, 50)
    
    # 创建Xarray数据集
    ds = xr.Dataset(
        {
            'temperature': (['time', 'latitude', 'longitude'], temperature),
        },
        coords={
            'time': times,
            'latitude': latitudes,
            'longitude': longitudes,
        }
    )
    
    # 对温度数据进行统计分析
    mean_temperature = ds['temperature'].mean(dim='time')
    max_temperature = ds['temperature'].max(dim='time')
    min_temperature = ds['temperature'].min(dim='time')
    
    # 打印数值
    print(f"mean temperature:n {mean_temperature}n")
    print(f"max temperature:n {max_temperature}n")
    print(f"min temperature:n {min_temperature}n")
    
    
    >>>
    
    mean temperature:
     
    array([[19.99931701, 20.36395016, 20.04110699, ..., 19.98811842,
            20.08895803, 19.86064693],
           [19.84016491, 19.87077812, 20.27445405, ..., 19.8071972 ,
            19.62665953, 19.58231185],
           [19.63911165, 19.62051976, 19.61247548, ..., 19.85043831,
            20.13086891, 19.80267099],
           ...,
           [20.18590514, 20.05931149, 20.17133483, ..., 20.52858247,
            19.83882433, 20.66808513],
           [19.56455575, 19.90091128, 20.32566232, ..., 19.88689221,
            19.78811145, 19.91205212],
           [19.82268297, 20.14242279, 19.60842148, ..., 19.68290006,
            20.00327294, 19.68955107]])
    Coordinates:
      * latitude   (latitude) float64 -90.0 -86.33 -82.65 ... 82.65 86.33 90.0
      * longitude  (longitude) float64 -180.0 -172.7 -165.3 ... 165.3 172.7 180.0
    
    max temperature:
     
    array([[29.98465531, 29.97609171, 29.96821276, ..., 29.86639343,
            29.95069558, 29.98807808],
           [29.91802049, 29.92870312, 29.87625447, ..., 29.92519055,
            29.9964299 , 29.99792388],
           [29.96647016, 29.7934891 , 29.89731136, ..., 29.99174546,
            29.97267052, 29.96058079],
           ...,
           [29.91699117, 29.98920555, 29.83798369, ..., 29.90271746,
            29.93747041, 29.97244906],
           [29.99171911, 29.99051943, 29.92706773, ..., 29.90578739,
            29.99433847, 29.94506567],
           [29.99438621, 29.98798699, 29.97664488, ..., 29.98669576,
            29.91296382, 29.93100249]])
    Coordinates:
      * latitude   (latitude) float64 -90.0 -86.33 -82.65 ... 82.65 86.33 90.0
      * longitude  (longitude) float64 -180.0 -172.7 -165.3 ... 165.3 172.7 180.0
    
    min temperature:
     
    array([[10.0326431 , 10.07666029, 10.02795524, ..., 10.17215336,
            10.00264909, 10.05387097],
           [10.00355858, 10.00610942, 10.02567816, ..., 10.29100316,
            10.00861792, 10.16955806],
           [10.01636216, 10.02856619, 10.00389027, ..., 10.0929342 ,
            10.01504103, 10.06219179],
           ...,
           [10.00477003, 10.0303088 , 10.04494723, ..., 10.05720692,
            10.122994  , 10.04947012],
           [10.00422182, 10.0211205 , 10.00183528, ..., 10.03818058,
            10.02632697, 10.06722953],
           [10.10994581, 10.12445222, 10.03002468, ..., 10.06937041,
            10.04924046, 10.00645499]])
    Coordinates:
      * latitude   (latitude) float64 -90.0 -86.33 -82.65 ... 82.65 86.33 90.0
      * longitude  (longitude) float64 -180.0 -172.7 -165.3 ... 165.3 172.7 180.0

    然后,获得了我们想要的结果,而且结果非常清晰易读。

    而且,正如之前所提到的,为了计算温度的最大值、最小值和平均值,本文使用了应用于数组的Pandas函数。

    结论

    在本文中,展示了三个用于数据处理和科学计算的库。

    虽然SymPy可以替代其他工具和软件,使我们能够使用Python代码进行数学计算,但Dask和Xarray扩展了其他库的功能,在我们使用其他更常用的Python库进行数据分析和处理时可能会遇到困难的情况下帮助我们。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论