如何利用Python計算景觀指數AI


1 可使用工具包

  • pylandstats
    • 此工具包基本是根據fragstats形成的,大部分fragstats里面的景觀指數,這里都可以計算。但是,還是有一小部分指數這里沒有涉及。
  • LS_METRICS

2 自定義的aggregation index(AI)計算

2.1 原理

\[AI=\frac{e_{ii}}{max\_e_{ii}}\times100 \]

  • 這里的\(e_{ii}\)是同類型像元公共邊的個數

  • \(max\_e_{ii}\)是同類型像元最大公共邊的個數, \(max\_e_{ii}\)的計算有公式可尋,具體計算公式如下:

    \[\begin{align*} & max\_eii = 2n(n-1), & when \quad m = 0, or\\ & max\_eii = 2n(n-1) + 2m -1, & when\quad m ≤ n, or\\ & max\_eii = 2n(n-1) + 2m -2, & when \quad m > n.\\ \end{align*} \]

    • n為不超過某個類型像元總面積\(A_i\)的最大整數正方形的邊長

    • m=\(A_i-n^2\)

實例

image

  • 例如圖a中類型1的聚居指數AI可為:

    \[\begin{align*} &e_{ii}=12\\ &max\_e{ii}=2n(n-1)=2\times3\times2=12\\ &AI=\frac{e_{ii}}{max\_e{ii}}\times100=100 \end{align*} \]

    這里AI為100是因為這里乘了一個系數100;

2.2 Python實現

  • 函數依賴關系

image

class AI(Landscape, ABC):
    def __init__(self, landscape, **kwargs):
        super().__init__(landscape, **kwargs)
	# 用於計算每種類型公共邊的數量
    def get_share_edge(self, class_):
        # 1.將數據轉換為二值型
        binary_data = (self.landscape_arr == class_).astype(np.int8)
        # 2.設置卷積模板
        cov_template = np.array([[0, 0, 0],
                                 [0, 0, 1],
                                 [0, 1, 0]])
        # 3.填充邊緣
        binary_pad = np.pad(binary_data, 1, mode='constant', constant_values=0)
        # 4.計算公共邊總數
        row_num, col_num = binary_pad.shape
        count = 0
        for i in range(1, row_num - 1):
            for j in range(1, col_num - 1):
                if binary_pad[i, j] == 1:
                    count += np.sum(binary_pad[i - 1:i + 2, j - 1:j + 2] * cov_template)
        return count
    
    # 計算eii
    @property
    def eii(self):
        return pd.Series([self.get_share_edge(class_) for class_ in self.classes], index=self.classes)
	# 計算最大的eii
    @property
    def max_eii(self):
        arr = self.landscape_arr
        flat_arr = arr.ravel()
        # 規避nodata值
        if self.nodata in flat_arr:
            a_ser = pd.value_counts(flat_arr).drop(self.nodata).reindex(self.classes)
        else:
            a_ser = pd.value_counts(flat_arr).reindex(self.classes)
        n_ser = np.floor(np.sqrt(a_ser))
        m_ser = a_ser - np.square(n_ser)
        max_eii = pd.Series(index=a_ser.index)
        for i in a_ser.index:
            if m_ser[i] == 0:
                max_eii[i] = (2 * n_ser[i]) * (n_ser[i] - 1)

            elif m_ser[i] <= n_ser[i]:
                max_eii[i] = 2 * n_ser[i] * (n_ser[i] - 1) + 2 * m_ser[i] - 1

            elif m_ser[i] >= n_ser[i]:
                max_eii[i] = 2 * n_ser[i] * (n_ser[i] - 1) + 2 * m_ser[i] - 2

        return max_eii
	# 計算AI指數
    def aggregation_index(self, class_val=None):
        """
        計算斑塊類型的聚集指數AI
        :param class_val: 整型,需要計算AI的斑塊類型代號
        :return: 標量數值或者Series
        """
        if len(self.classes) < 1:
            warnings.warn("當前數組全是空值,沒有需要計算的類型聚集指數",
                          RuntimeWarning,
                          )
            return np.nan
        if class_val is None:
            return (self.eii / self.max_eii) * 100
        else:
            return ((self.eii / self.max_eii) * 100)[class_val]

3 參考文獻

  1. An aggregation index (AI) to quantify spatial patterns of landscapes
  2. http://www.umass.edu/landeco/research/fragstats/documents/Metrics/Contagion - Interspersion Metrics/Metrics/C116 - AI.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM