插值運算是一種數據處理方法,主要用來填補數據之間的空白或缺失值。因為在實際應用中,數據往往不是完整的,而是存在著空白或缺失值,這些空白或缺失值可能是由於數據採集困難、數據丟失或數據處理錯誤等原因造成的。如果直接使用這些空白或缺失值進行分析和預測,將會對結果造成很大的影響。 插值運算可以用來填補這些空 ...
插值運算是一種數據處理方法,主要用來填補數據之間的空白或缺失值。
因為在實際應用中,數據往往不是完整的,而是存在著空白或缺失值,這些空白或缺失值可能是由於數據採集困難、數據丟失或數據處理錯誤等原因造成的。
如果直接使用這些空白或缺失值進行分析和預測,將會對結果造成很大的影響。
插值運算可以用來填補這些空白或缺失值,從而恢復完整的數據集。
通過插值運算,可以估算出空白或缺失值的值,從而提高數據的完整性和準確性。
此外,插值運算還可以用來預測未來的數據趨勢或結果,對於數據分析和預測具有重要的意義。
本篇介紹Scipy
為我們提供的插值處理方法。
1. 主要功能
Scipy
中,關於插值的子模塊是:scipy.interpolate
。
其中又細分為:
類別 | 說明 |
---|---|
單變數插值 | 主要包含interp1d 等12個函數 |
多變數插值 | 主要包含griddata 等11個函數 |
一維樣條函數 | 主要包含BSpline 等16個函數 |
二維樣條函數 | 主要包含RectBivariateSpline 等9個函數 |
其他函數 | 一些輔助計算的函數 |
插值效果的好壞,有個重要的因素在於是否根據數據的情況選擇了合適的插值演算法。Scipy
庫中已經實現的插值演算法有:
- linear:線性插值演算法
- nearest:最近鄰插值演算法
- nearest-up:改進型最近鄰插值演算法
- zero:零階樣條插值演算法(等同於 previous)
- slinear:一階樣條插值演算法(等同於 linear)
- quadratic:五階樣條插值演算法
- cubic:三階樣條插值演算法
- previous:前點插值演算法
- next:後點插值演算法
我們可以根據數據情況選擇合適的演算法,下麵用一些測試數據演示不同演算法的插值效果:
from scipy.interpolate import interp1d
x = np.linspace(0, 20, 20)
y = x * np.cos(x)
plt.scatter(x,y)
plt.show()
上圖是插值之前,直接由20個數據點連接起來的折線。
接下來,應用9種不同的插值演算法將20
個點補充為100
個點,然後看看插值之後各種曲線的效果。
interp_types = [
"linear",
"nearest",
"nearest-up",
"zero",
"slinear",
"quadratic",
"cubic",
"previous",
"next",
]
fig = plt.figure(figsize=[12, 9])
fig.subplots_adjust(hspace=0.4)
for idx, typ in enumerate(interp_types):
f = interp1d(x, y, kind=typ)
x_dense = np.linspace(0, 20, 100)
y_dense = f(x_dense)
ax = fig.add_subplot(330 + idx+1)
ax.scatter(x, y)
ax.plot(x_dense, y_dense, color='g')
ax.set_title("插值演算法-{}".format(typ))
plt.show()
2. 一維插值示例
在我自己實際接觸的項目中,氣象數據的處理經常會用到插值。
因為氣象數據常常存在缺失值,這可能是由於感測器故障,數據傳輸問題,或者在某些情況下,由於天氣現象使得數據無法收集。
對於這些缺失值,我們可以使用Scipy
的一維插值功能來進行填充。
比如下麵是南京市某年的各個月的平均氣溫:
import pandas as pd
# 南京一年中每個月平均氣溫
df = pd.DataFrame({
"月份": ["一月", "二月", "三月",
"四月", "五月", "六月",
"七月", "八月", "九月",
"十月", "十一月", "十二月"],
"平均最低氣溫": [-1.6, 0.0, 4.4,
np.nan, 15.7, 20.4,
np.nan, 24.6, 19.1,
12.6, 6.1, -0.1],
"平均最高氣溫": [7.0, 8.4, np.nan,
20.1, 25.3, 29.0,
32.0, 32.2, 27.2,
np.nan, 16.9, 9.7],
})
df
由於採集或者傳輸的原因,導致缺失了一些數據。
這樣的數據不僅繪製出來的折線圖會有斷開的地方,而且不利於後續的分析。
plt.plot(df["月份"], df["平均最低氣溫"], label="平均最低氣溫")
plt.plot(df["月份"], df["平均最高氣溫"], label="平均最高氣溫")
plt.legend()
plt.show()
這時,可以用Scipy
的插值演算法來補充缺失數據。
from scipy.interpolate import interp1d
# 過濾掉缺失的 平均最低氣溫 數據
df_low =df[df["平均最低氣溫"].notna()]
# 根據已有的數據生成插值函數
f = interp1d(df_low.index, df_low["平均最低氣溫"], kind="cubic")
# 用插值函數補充缺失數據
df["平均最低氣溫"] = f(range(12))
# 平均最高氣溫 的缺失數據處理同上
df_high =df[df["平均最高氣溫"].notna()]
f = interp1d(df_high.index, df_high["平均最高氣溫"], kind="cubic")
df["平均最高氣溫"] = f(range(12))
df.round(1)
plt.plot(df["月份"], df["平均最低氣溫"], label="平均最低氣溫")
plt.plot(df["月份"], df["平均最高氣溫"], label="平均最高氣溫")
plt.legend()
plt.show()
處理之後,數據的連續性更好了。
3. 二維插值示例
當自變數有2個的時候,就要用到二維插值了。
仍然以氣象上的數據舉例,上面示例是氣溫和時間的關係,我們把時間作為自變數,只要一維插值即可。
如果是和地點關聯的話,那麼地點作為自變數就有2個值(一般是經度和緯度)。
比如下麵截取了項目中一段降水量的數據:
# 數據是二維數組:
# 每一行代表經度相同,緯度不同的地點
# 每一列代表緯度相同,經度不同的地點
data = np.array([
[9, 9, 5, 9, 10, 9, 8, 7, 11, 1],
[54, 36, 54, 32, 46, 51, 35, 33, 36, 11],
[35, 34, 34, 45, 52, 35, 34, 36, 41, 9],
[117, 112, 113, 133, 126, 127, 119, 96, 116, 23],
[110, 67, 91, 85, 94, 69, 77, 81, 65, 13],
[9, 7, 13, 12, 9, 6, 8, 9, 21, 3],
[50, 21, 24, 32, 36, 26, 28, 30, 24, 3],
[65, 41, 63, 67, 58, 50, 54, 45, 48, 16],
[36, 29, 32, 28, 38, 29, 41, 27, 29, 9],
[37, 61, 57, 35, 56, 51, 40, 58, 100, 34],
])
顯示降水量的分佈情況。
plt.imshow(data, cmap=plt.cm.GnBu)
plt.colorbar()
plt.xticks([])
plt.yticks([])
plt.show()
data
中只有100個數據,所以每個格子一個值,看起來不是那麼連續,
而實際的降水情況不會像這樣離散的,區域之間的降水量應該是逐漸連續變化的。
所以,需要在data
的基礎上進行二維插值:
from scipy.interpolate import RectBivariateSpline
# 原始數據是 10x10
x = np.linspace(0, 10, 10, endpoint=False)
y = np.linspace(0, 10, 10, endpoint=False)
# 插值後的數據是 500x500
x_new = np.linspace(0, 10, 500, endpoint=False)
y_new = np.linspace(0, 10, 500, endpoint=False)
# 從原始數據生成插值函數
f = RectBivariateSpline(x, y, data.T)
# 用插值函數計算新的數據
data_new = f(x_new, y_new)
# 顯示插值後的結果
plt.imshow(data_new.T, cmap=plt.cm.GnBu)
plt.colorbar()
plt.xticks([])
plt.yticks([])
plt.show()
這是插值到 500x500
的效果,值越大,連續性越好。
有興趣的話,可以調整上面代碼中 x_new
和 y_new
的個數,看看不同的效果。
4. 總結
插值作為一種常見的數據處理方法,應用的領域和場景非常多,比如:
- 數據預測:通過插值技術,可以預測未來的數據趨勢或結果。
- 圖像處理:插值可以用於圖像處理和圖像分析,以提高圖像的解析度或質量。
- 機器學習:插值技術也可以用於機器學習和人工智慧領域。用於構建回歸模型或分類模型,以便對未知數據進行預測或分類。
本文主要介紹了Scipy庫的插值子模塊,其內置的插值演算法,以及兩個應用插值的小例子。