Python/ target=_blank class=infotextkey>Python是世界上使用最廣泛的編程語言之一,并為開發(fā)人員提供了大量的庫。
然而,當涉及到數(shù)據(jù)處理和科學計算時,用戶通常會想到諸如Numpy、Pandas或SciPy等庫。
在本文中,將介紹3個你可能感興趣的Python庫。
1.Dask
Dask簡介
Dask是一個靈活的并行計算庫,可實現(xiàn)大規(guī)模數(shù)據(jù)處理的分布式計算和并行計算。
那么,為什么用戶要使用Dask呢?正如他們在其網(wǎng)站上所說的:
【Dask】:https://www.dask.org/
Python已經(jīng)發(fā)展成為數(shù)據(jù)分析和通用編程中的主流語言。這種增長得益于像NumPy、Pandas和scikit-learn等計算庫。然而,這些包并不適用于超越單臺機器的規(guī)模。當數(shù)據(jù)集超過內(nèi)存時,Dask被開發(fā)出來原生地擴展這些包及其周邊生態(tài)系統(tǒng),以適應多核機器和分布式集群。
因此,正如他們所說,Dask的一個常見用途是:
【鏈接】:https://docs.dask.org/en/latest/dataframe.html
當需要像使用Pandas一樣常用時,使用Dask DataFrame,通常是因為Pandas在處理數(shù)據(jù)量或計算速度方面存在問題:
- 處理大型數(shù)據(jù)集,即使這些數(shù)據(jù)集無法容納在內(nèi)存中
- 通過使用多個內(nèi)核加速長時間計算
- 對使用標準Pandas操作的大型數(shù)據(jù)集進行分布式計算,例如groupby、join和時間序列計算
因此,當需要處理巨大的Pandas數(shù)據(jù)幀時,Dask是一個不錯的選擇。這是因為Dask可以:
允許用戶在筆記本電腦上處理100GB以上的數(shù)據(jù)集,或者在工作站上處理1TB以上的數(shù)據(jù)集。
這是一個相當了不起的結(jié)果。
在幕后發(fā)生的情況是:
Dask DataFrames協(xié)調(diào)許多按索引排列的Pandas DataFrames/Series。Dask DataFrame以行為單位進行分區(qū),通過索引值對行進行分組,以提高效率。這些Pandas對象可以存在于磁盤上或其他機器上。
因此,有類似的如下情況:
Dask和Pandas數(shù)據(jù)幀的區(qū)別。
運行中的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上執(zhí)行操作
mean_value_dask = df_dask['column_name'].mean().compute()
因此,正如在代碼中看到的,本文使用Dask的方式與Pandas非常相似。尤其是:
- 使用read_csv()方法與Pandas完全相同
- 截取列的方式與Pandas完全相同。事實上,如果有一個名為df的Pandas數(shù)據(jù)框架,我們會這樣截取一列:df['column_name']。
- 將mean()方法應用于截取的列,這與Pandas類似,但這里還需要添加compute()方法。
此外,即使打開CSV文件的方法與Pandas相同,Dask也能毫不費力地處理超過單臺機器內(nèi)存容量的大型數(shù)據(jù)集。
這意味著,除了在Pandas中無法打開大型數(shù)據(jù)幀,而在Dask中可以打開之外,無法看到任何實際的差異。
功能二:擴展機器學習工作流程
可以使用Dask創(chuàng)建一個具有大量樣本的分類數(shù)據(jù)集。然后可以將其分割為訓練集和測試集,使用機器學習模型擬合訓練集,并計算測試集的預測結(jié)果。
可以這樣做,如下所示:
import dask_ml.datasets as dask_datasets
from dask_ml.linear_model import LogisticRegression
from dask_ml.model_selection import trAIn_test_split
# 使用Dask加載分類數(shù)據(jù)集
X, y = dask_datasets.make_classification(n_samples=100000, chunks=1000)
# 將數(shù)據(jù)分割為訓練集和測試集
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()
該示例強調(diào)了Dask處理大規(guī)模數(shù)據(jù)集的能力,即使是在機器學習問題的情況下,也可以通過在多個內(nèi)核之間分布計算來實現(xiàn)。
具體而言,可以使用dask_datasets.make_classification()方法為分類問題創(chuàng)建一個“Dask dataset” ,并且可以指定樣本數(shù)量和塊大小(甚至是非常巨大的數(shù)量)。
與之前類似,預測結(jié)果是通過compute()方法獲得的。
# 注意:
# 在這種情況下,可能需要安裝模塊`dask_ml`。
# 可以按以下方式進行安裝:
$ pip install dask_ml
功能三:高效圖像處理
Dask所利用的并行處理能力也可以應用于圖像處理。
特別是可以打開多個圖像,調(diào)整其大小,并保存調(diào)整后的圖像。可以按以下方式操作:
import dask.array as da
import dask_image.imread
from PIL import Image
# 使用Dask加載圖像集合
images = dask_image.imread.imread('image*.jpg')
# 并行調(diào)整圖像大小
resized_images = da.stack([da.resize(image, (300, 300)) for image in images])
# 計算結(jié)果
result = resized_images.compute()
# 保存調(diào)整后的圖像
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()方法和列表推導式將所有圖像的大小調(diào)整為300x300。
- 使用compute()方法計算結(jié)果,就像之前一樣。
- 使用for循環(huán)保存所有調(diào)整過大小的圖像。
2.SymPy
Sympy簡介
如果需要進行數(shù)學計算,并希望使用Python進行操作,可以嘗試使用SymPy。
正如他們在網(wǎng)站上所寫的介紹那樣,Sympy是:
【Sympy】:https://www.sympy.org/en/index.html
一個用于符號數(shù)學的Python庫。它旨在成為一個功能齊全的計算機代數(shù)系統(tǒng)(CAS),同時保持代碼盡可能簡單,以便易于理解和擴展。SymPy完全使用Python編寫。
但是為什么要使用SymPy?他們提到:
SymPy具有以下特點:
- 免費:SymPy采用BSD許可證,既具有言論自由,也免費。
- 基于Python:SymPy完全使用Python編寫,并使用Python作為其語言。
- 輕量級:SymPy僅依賴于mpmath,這是一個用于任意浮點數(shù)算術的純Python庫,因此易于使用。
- 作為庫存在:除了作為交互工具使用外,SymPy還可以嵌入到其他應用程序中,并使用自定義函數(shù)進行擴展。
因此,它基本上具備了所有Python愛好者所喜愛的特性!
現(xiàn)在來查看一下它的部分功能。
SymPy的一些功能
首先,需要安裝它:
$ pip install sympy
請注意:
如果寫成`$ pip install simpy`,將安裝另一個(完全不同的!)庫。
因此,第二個字母是"y",而不是"i"。
功能一:解代數(shù)方程
如果需要解代數(shù)方程,可以這樣使用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方法編寫代數(shù)方程。
- 使用solve()方法解方程。
正如上述所看到的,SymPy是一個非常易讀和用戶友好的Python庫。
功能二:計算導數(shù)
計算導數(shù)是在分析數(shù)據(jù)時可能需要的另一個數(shù)學任務,原因有很多。通常情況下,可能因為各種原因需要進行計算,而SymPy真正簡化了這個過程。實際上,可以這樣做,如下所示:
from sympy import symbols, diff
# 定義符號
x = symbols('x')
# 定義函數(shù)
f = x**3 + 2*x**2 + 3*x + 4
# 計算導數(shù)
derivative = diff(f, x)
# 打印導數(shù)
print(derivative)
>>>
3*x**2 + 4*x + 3
因此,正如上述所看到的,這個過程非常簡單和容易自解釋:
- 使用symbols()方法定義要求導的函數(shù)的符號。
- 定義函數(shù)。
- 使用diff()計算導數(shù),并指定函數(shù)和要計算導數(shù)的符號(這是一個絕對導數(shù),但在具有x和y變量的函數(shù)的情況下,甚至也可以進行計算偏導數(shù))。
如果進行測試,就會發(fā)現(xiàn)結(jié)果在2或3秒鐘內(nèi)就會出現(xiàn)。因此,它的速度也相當快。
功能三:計算積分
當然,如果SymPy可以計算導數(shù),它也可以計算積分。接下來嘗試做一下:
from sympy import symbols, integrate, sin
# 定義符號
x = symbols('x')
# 執(zhí)行符號積分
integral = integrate(sin(x), x)
# 打印積分
print(integral)
>>>
-cos(x)
所以,本文在這里使用integrate()方法,指定要積分的函數(shù)和積分變量。
3.Xarray
Xarray簡介
Xarray是一個擴展了NumPy特性和功能的Python庫,使用戶能夠使用帶有標簽的數(shù)組和數(shù)據(jù)集進行工作。
事實上,正如他們在官網(wǎng)上所說的那樣:
【Xarray】:https://docs.xarray.dev/en/stable/
Xarray使得在Python中處理帶有標簽的多維數(shù)組變得簡單、高效和有趣!
還有:
【鏈接】:https://docs.xarray.dev/en/stable/getting-started-guide/why-xarray.html
Xarray在類似于NumPy的原始多維數(shù)組之上引入了維度、坐標和屬性形式的標簽,這使得開發(fā)者的體驗更加直觀、簡潔,減少了錯誤的發(fā)生。
換句話說,它通過向數(shù)組維度添加標簽或坐標來擴展NumPy數(shù)組的功能。這些標簽提供了元數(shù)據(jù),可以對多維數(shù)據(jù)進行更高級的分析和操作。
例如,在NumPy中,使用基于整數(shù)的索引訪問數(shù)組。
而在Xarray中,每個維度都可以關聯(lián)一個標簽,這樣就可以根據(jù)有意義的名稱更容易地理解和操作數(shù)據(jù)。
例如,在Xarray中,用戶可以使用arr.sel(x=0, y=1, z=2)來訪問數(shù)據(jù),其中x、y和z是維度的標簽,而不是使用arr[0, 1, 2]來訪問數(shù)據(jù)。
這使得代碼更加易讀!
接下來查看一些Xarray的功能。
一些Xarray的功能
像往常一樣,首先要安裝它:
$ pip install xarray
功能一:使用標注坐標
假設用戶想創(chuàng)建與溫度相關的一些數(shù)據(jù),并且想將它們標記為緯度和經(jīng)度等坐標。可以這樣做:
import xarray as xr
import numpy as np
# 創(chuàng)建溫度數(shù)據(jù)
temperature = np.random.rand(100, 100) * 20 + 10
# 創(chuàng)建經(jīng)緯度坐標數(shù)組
latitudes = np.linspace(-90, 90, 100)
longitudes = np.linspace(-180, 180, 100)
# 創(chuàng)建帶有標注坐標的Xarray數(shù)據(jù)數(shù)組
da = xr.DataArray(
temperature,
dims=['latitude', 'longitude'],
coords={'latitude': latitudes, 'longitude': longitudes}
)
# 使用標注坐標訪問數(shù)據(jù)
subset = da.sel(latitude=slice(-45, 45), lnotallow=slice(-90, 0))
如果打印出來,就會得到
# 打印數(shù)據(jù)
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
所以,接下來逐步了解這個過程:
- 將溫度值創(chuàng)建為一個NumPy數(shù)組。
- 將緯度和經(jīng)度值定義為NumPy數(shù)組。
- 使用DataArray()方法將所有數(shù)據(jù)存儲在一個Xarray數(shù)組中。
- 使用sel()方法選擇了一個經(jīng)緯度子集,該方法為子集選擇了我們想要的值。
這樣得到的結(jié)果也很容易閱讀,因此標簽在很多情況下非常有幫助。
功能二:處理缺失數(shù)據(jù)
假設用戶正在收集與一年中與溫度相關的數(shù)據(jù)。并且想知道數(shù)組中是否有空值。如下是用戶可以這樣做的方法:
import xarray as xr
import numpy as np
import pandas as pd
# 創(chuàng)建有缺失值的溫度數(shù)據(jù)
temperature = np.random.rand(365, 50, 50) * 20 + 10
temperature[0:10, :, :] = np.nan # Set the first 10 days as missing values
# 創(chuàng)建時間、緯度和經(jīng)度坐標數(shù)組
times = pd.date_range('2023-01-01', periods=365, freq='D')
latitudes = np.linspace(-90, 90, 50)
longitudes = np.linspace(-180, 180, 50)
# 創(chuàng)建帶有缺失值的Xarray數(shù)據(jù)數(shù)組
da = xr.DataArray(
temperature,
dims=['time', 'latitude', 'longitude'],
coords={'time': times, 'latitude': latitudes, 'longitude': longitudes}
)
# 沿時間維度計算缺失值的數(shù)量
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個空數(shù)值。
此外,如果我們仔細查看代碼,就會發(fā)現(xiàn)我們可以將Pandas的方法應用到Xarray中,比如isnull.sum(),在本例中,它可以計算缺失值的總數(shù)。
功能三:處理和分析多維數(shù)據(jù)
當我們可以給數(shù)組貼標簽時,處理和分析多維數(shù)據(jù)的誘惑就會很大。那么,接下來跟隨本文進行嘗試。
例如,假設用戶仍在收集與特定緯度和經(jīng)度相關的溫度數(shù)據(jù)。
我們可能想要計算溫度的平均值、最大值和中值。可以進行如下操作:
import xarray as xr
import numpy as np
import pandas as pd
# 創(chuàng)建合成溫度數(shù)據(jù)
temperature = np.random.rand(365, 50, 50) * 20 + 10
# 創(chuàng)建時間、緯度和經(jīng)度坐標數(shù)組
times = pd.date_range('2023-01-01', periods=365, freq='D')
latitudes = np.linspace(-90, 90, 50)
longitudes = np.linspace(-180, 180, 50)
# 創(chuàng)建Xarray數(shù)據(jù)集
ds = xr.Dataset(
{
'temperature': (['time', 'latitude', 'longitude'], temperature),
},
coords={
'time': times,
'latitude': latitudes,
'longitude': longitudes,
}
)
# 對溫度數(shù)據(jù)進行統(tǒng)計分析
mean_temperature = ds['temperature'].mean(dim='time')
max_temperature = ds['temperature'].max(dim='time')
min_temperature = ds['temperature'].min(dim='time')
# 打印數(shù)值
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
然后,獲得了我們想要的結(jié)果,而且結(jié)果非常清晰易讀。
而且,正如之前所提到的,為了計算溫度的最大值、最小值和平均值,本文使用了應用于數(shù)組的Pandas函數(shù)。
結(jié)論
在本文中,展示了三個用于數(shù)據(jù)處理和科學計算的庫。
雖然SymPy可以替代其他工具和軟件,使我們能夠使用Python代碼進行數(shù)學計算,但Dask和Xarray擴展了其他庫的功能,在我們使用其他更常用的Python庫進行數(shù)據(jù)分析和處理時可能會遇到困難的情況下幫助我們。