【Python】使用Python调用Fragstats批量进行万级及以上数据的景观指数运算

10 篇文章 22 订阅

1 简介

两个月前师姐替别人问我一个问题,
在这里插入图片描述
在这里插入图片描述
当时仅仅只是会使用界面化的fragstats,再加上搜遍全网也没搜到使用python进行批量景观指数计算的方法,因此没能很好地回答师姐朋友的问题,但是还是通过检索推荐了一些材料(材料1材料2),感兴趣的同学们可以参考一下。
后来在做一个课题时(景观层面的指标计算),我自己也要使用大规模的fragstats运算,才花点时间好好静下心来研究这个题目所提到的内容。
这应该是第一个使用python调用fragstats批量进行万级及以上数据的景观指数运算的代码教程,并且在博文的末尾还提供了0代码的傻瓜解决方案(可以直接跳转到本文第4节)(但是我建议大家看完全文再寻求傻瓜方案,或者至少熟悉界面化的fragstats操作)。

开始说正题——
重点——本文针对的场景是:已经通过arcgis或其他方法制作了渔网(fishnet)并且把一个tif根据渔网格网分裂成成千上万个带编号的小方格tif集,本文的目标在于接下来计算这些带编号的小方格tif集的各种景观指数。在这里,本文假设同学们已经会使用界面化的fragstats,并且会制作批量景观计算的fbt脚本文件(也就是import batch需要导入的文件)。

本文思路在于:
1,为了解决fragstats这个软件原生性的问题,即单个过大脚本容易报错,所以要切割拆分脚本,将其分割成多个批量任务进行景观指数计算;
2,可以通过python调用cmd再调用fragstats的frg.exe文件计算景观指数(关于cmd调用fragstats可以看这篇博文),从而实现自动完成多个批量任务(注意,这里是批量完成批量脚本任务,即批量的批量)。

因此,本文包括以下两部分:
1,拆分批量运算的脚本文件(默认为fbt文件,但本文中为了方便使用csv格式的脚本);
2,根据脚本文件集批量计算景观指数。

2 拆分和合并脚本文件

在这里已经假设了各位同学知道脚本文件的构成并且知道如何制作批量运算脚本文件,所以不多赘述。如果有不清楚的可以参考这篇博文

我的其中一个脚本文件长下面这个样子,我为了方便存成csv格式的,当然你要存txt或者默认的fbt都行,只需要稍微修改一下我后面要提到的代码。
在这里插入图片描述
然后我使用代码将它分裂成30个(只展示其中一部分)。
在这里插入图片描述

在这里插入图片描述
然后。。然后就没了。。
但是关键的来了,下面是代码,要用到的依赖包很少,只有两个基础包+一个pandas(pandas也很基础,没有装的自己反思一下然后光速安装)。

import pandas as pd
import os
import glob

def merge_csv(files_dir, outpath): # 将多个csv文件合并为一个,待合并csv集目录,合并后csv文件路径
    csv_files = glob.glob(os.path.join(files_dir, "*.csv")) # 抓取目录下全部csv文件
    features = pd.DataFrame() # 生成一个DF格式要素
    for csv_file in csv_files:
        feature = pd.read_csv(csv_file) # 读取单个csv文件
        features = features.append(feature) # 添加进要素集
    features.to_csv(outpath, index=False, encoding="utf-8") # 导出为csv文件
    print("merged successfully!")

def split_csv(csv_file, outdir, count): # 将一个csv文件拆分为多个,待拆分csv文件,拆分保存目录,拆分个数
    feature = pd.read_csv(csv_file) # 读取csv
    feature = pd.DataFrame(feature)
    num = int(len(feature)/count) # 单个文件个数
    for i in range(count):
        start = i * num
        end = (i+1) * num
        if i == 0:
            start = 0
        if i == count-1:
            end = len(feature)
        feature_single = feature.iloc[start:end, :]
        file_name = os.path.splitext(os.path.split(csv_file)[1])[0]
        comlete_name = f"{file_name}_{str(i+1)}_{end-start}count"
        outpath = os.path.join(outdir, comlete_name + ".csv")
        feature_single.to_csv(outpath, index=False, encoding="utf-8") # 导出为csv文件
        print(f"{comlete_name} split successfully")

model = input("请输入模式(1:合并 2:拆分):")
if model == "1":
    print("\n==================== 进入合并模式 ====================\n")
    files_dir = input("请输入待合并的csv文件集目录:")
    outpath = input("请输入合并后文件的输出路径:")
    merge_csv(files_dir, outpath)
    print("\n=====================================================")
if model == "2":
    print("\n==================== 进入拆分模式 ====================\n")
    csv_file = input("请输入待拆分的csv文件路径:")
    outdir = input("请输入拆分后文件集的输出路径:")
    counts = input("请输入该csv文件的拆分个数:")
    counts = int(counts)
    split_csv(csv_file, outdir, counts)
    print("\n=====================================================")

代码是傻瓜式代码,因为使用了input语句,所以一上去运行就行了(但是理解起来也不难)。

运行完分为两种模式,模式1是合并,是为了将一些稀碎的脚本或最终计算完成的结果合并为一个csv准备的;模式2是拆分,就是本小节的主要任务。因为直接使用了input,所以代码也可以直接使用命令行调用。

拆分的操作如下(其实只要按指引填上相关的路径和信息即可):
在这里插入图片描述
需要注意的是,拆分后的文件除了增加文件的索引(就是1到30)还增加了文件内条目的个数,这对于我们控制fragstats的运算是有帮助的,因为如果一个脚本里太多条目了容易崩掉(懂得都懂)。。。并且这个崩不崩掉和电脑的性能关系不是太大,在这里的批量运算中建议拆分后单个脚本的条目个数<300(亲测最稳定快速)。

至于合并就不展示了,就是倒过来操作,运行一下选模式1根据指引输入参数就可。

再补充一点,这个代码目前只能识别csv文件,会无视掉同一个目录下的其他格式文件,有其他需求的可以自己改改,改完可以识别.class文件。

3 根据脚本集批量计算景观指数

在开始通过python调用fragstats计算景观指数前,为了确保代码能够使用,需要把fragstats安装目录添加到环境变量中,如下图。
在这里插入图片描述
变量值填你自己的路径奥,别照搬我的。不懂得配置环境变量的同学可以另行百度。

你如果跟我皮,不添加也行,可以直接使用frg.exe的绝对路径运行fragstats,具体在这里不细说,有需要的同学可以参考这篇博文的方法修改代码。

下面是代码(添加环境变量后才能良好运行的代码,没添加的自己改改),一样,使用了input,直接运行然后输入参数即可。

import os
from glob import glob
import pandas as pd

def frg_cmd(model, scripts_dir, output_dir): # 模型路径,脚本所在目录,输出目录
    csv_scripts = glob(os.path.join(scripts_dir, "*.csv")) # 抓取目录下全部csv文件
    for csv_script in csv_scripts:
        output_file = os.path.join(output_dir, os.path.split(csv_script)[1])
        output_file = os.path.splitext(output_file)[0]
        print("=====================================================")
        print(f"model: {model}")
        print(f"script: {csv_script}")
        print(f"output: {output_file}")
        print("\n")
        frg_flag = 0
        while frg_flag == 0:
            os.system(f"frg -m {model} -b {csv_script} -o {output_file}") # 命令行执行
            read_csv_script = pd.read_csv(csv_script) # 读取脚本文件
            read_output_file = pd.read_csv(output_file+".class") # 读取输出文件
            read_csv_script = pd.DataFrame(read_csv_script)
            read_output_file = pd.DataFrame(read_output_file)
            if len(read_csv_script) == len(read_output_file): # 如果条目数匹配
                frg_flag = 1
                print("data match!")
            else:
                print("data do not match! Restart!")
        print("\n")
        print(f"{output_file} is completed!")
        print("=====================================================")

model = input("请输入模型路径:")
scripts_dir = input("请输入脚本目录:")
output_dir = input("请输入输出目录:")
frg_cmd(model, scripts_dir, output_dir)

模型路径,就是你在界面化中勾选的一些要计算的景观指数然后保存的.fca文件。
脚本目录,就是上面制作的csv脚本的目录,在这个代码默认只能识别csv格式的脚本。
输出目录,就是你要保存结果的目录。

我输入的信息如下,可以参考(根据实际情况设置,不要无脑照抄):
在这里插入图片描述
然后就是和在界面化fragstats终端中输出的信息类似的,首先是加载,
在这里插入图片描述
然后是分析计算,
在这里插入图片描述
需要注意的是,我的代码中加入了输出结果的脚本中数量的比对,如果数量不一致就会自动重新计算,这样可以避免出错漏算一些条目(解决脚本中条目太多会中断漏算的问题),所以还是建议大家把每个脚本的条目数弄少一点(建议<300)。

最后等终端显示计算完成出现相关提示后就可以在你的输出文件夹里看到.class的结果文件了。

我一般是把后缀直接改成.csv打开就行了。
在这里插入图片描述
上图中我先跑出了三个(为了写博客没必要都跑出来结果),我的电脑跑一个200+条目(格子)的脚本的结果大概花不到1分钟,简单来说就是不慢。

我自己的一个研究二十多万个条目(tif或格子)分成1000+个csv也才用不到一天时间,如果想要很快可以放在多台电脑上,这东西不需要什么算力。

说回正题,把导出的结果.class文件改成.csv后缀直接打开如下。
在这里插入图片描述
好了,这就得到我们最终需要的结果了。
如果需要合并结果,用第2节的代码切到合并格式然后输入相关信息合并即可。

4 懒得学python或者没有python环境的解决方案

我简单把上面两个代码封装了一下,方便不会python或没有python环境的同学。

这两个exe在一般windows电脑都可以运行,打开即可(但是仍然用要把fragstats添加到环境变量中)。

现在只要V我50吃顿肯德基,即可获取下面两个封装后的傻瓜版exe。

重新说一边奥,为了帮助到没有python环境和不会python同学(会python的同学直接运行第2、3节的代码,不用再问我啦),我把上面的代码封装成两个小程序,直接打开即可实现类似上面的操作。但是下面两个小程序是有偿获取的知识付费,随便打赏50元以上即可),需要的同学可以联系我邮箱(chinshuuichi@qq.com)并且贴上打赏付款证明(码在下面),我看到后就会在附件中贴上这两个小程序给你。(记得在邮件里说明要哪篇博客的材料啊!之前一些博客也有提供类似有偿服务,总是有同学不说明要啥,很耽误时间。)
在这里插入图片描述
如果对你有帮助,还望支持一下~点击此处施舍或扫下图的码。
-----------------------分割线(以下是乞讨内容)-----------------------
在这里插入图片描述

Fragstats是一个广泛使用景观分析软件,可用于计算各种景观指数,包括斑块密度、斑块大小、分离度等。以下是使用Fragstats 4.2进行景观指数计算的步骤: 1. 准备数据 在开始计算之前,您需要准备用于计算的数据。这可能包括栅格图像或矢量数据。如果您使用的是栅格图像,则需要将其转换为矢量数据。 2. 安装Fragstats 您需要在计算机上安装Fragstats软件。您可以从官方网站(http://www.umass.edu/landeco/research/fragstats/fragstats.html)下载最新版本的软件。 3. 打开Fragstats 打开Fragstats软件后,选择“File”菜单中的“New Project”选项。然后,选择您要计算的数据文件并输入项目名称。 4. 创建景观指数 选择“Analysis”菜单中的“Landscape Metrics”选项。在弹出的对话框中,选择要计算的景观指数。您可以选择从多个指数进行选择,例如斑块密度、斑块大小、分离度等。 5. 配置参数 在选择景观指数后,您需要配置计算参数。这可能包括指标类型、计算方式、距离阈值等。您可以在Fragstats文档中找到有关每个参数的详细信息。 6. 运行计算 完成参数配置后,单击“OK”按钮运行计算。Fragstats将生成一个报告,其中包含计算结果和图表。 7. 分析结果 分析Fragstats生成的报告以理解计算结果。您可以使用这些结果来评估景观特征,帮助指导土地管理和规划决策。 这些是使用Fragstats 4.2进行景观指数计算的基本步骤。请注意,Fragstats拥有广泛的文档和支持社区,可以提供更详细的指导和帮助。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值