[MODIS数据处理#6]检查大批量下载MODIS数据序列中的重复、缺失文件

一、问题描述

在大批量下载MODIS某产品数据时,可能会出现时间序列缺失、或者重复的问题。例如,下载中国北部(共13个区块)MOD16A2产品,时间跨度为2000~2020年,时间分辨率为8-day。下载后的文件数目及大小如下:
[MODIS数据处理#6]检查大批量下载MODIS数据序列中的重复、缺失文件_第1张图片
总文件数目有一万多,在研究某一数据随着时间的变化时,需要保证时间序列的完整性。但由于下载时的某些原因会出现下图中的情形:在2016041与2016057之间缺失了2016049这一天的数据。
[MODIS数据处理#6]检查大批量下载MODIS数据序列中的重复、缺失文件_第2张图片
在MODIS数据时间跨度小时,缺失文件可以通过观察逐一找到。针对文件数目极多的情形,尝试用python编程来自动查找序列中的缺失文件会更好。

二、功能介绍

1、显示统计信息,包含hdf文件总数目,各级分类下对应的文件数目。
在这里插入图片描述
2、显示时间序列中的重复文件与缺失文件

三、代码

"""
@project_ = 'gdal练习'
@file_name__ = Salierib
@author__ = 'Administrator'
@time = '2020/8/8 0008 20:54'
"""

import os
from pprint import pprint
from collections import Counter


def show_files(path, all_files, suffix=".hdf"):
    """
    :param path:待遍历的文件夹路径
    :param all_files:存放特定格式文件的容器
    :param suffix:目标文件的后缀
    :return:
    """
    #  首先遍历当前目录下指定后缀的所有文件(包含子文件夹)
    file_list = os.listdir(path)
    # 准备循环判断每个元素是否是文件夹还是文件,是文件的话,把名称传入list,是文件夹的话,递归
    for file in file_list:
        # 利用os.path.join()方法取得路径全名,并存入cur_path变量,否则每次只能遍历一层目录
        cur_path = os.path.join(path, file)
        # 判断是否是文件夹
        if os.path.isdir(cur_path):
            show_files(cur_path, all_files)
        else:
            if file.endswith(suffix):
                all_files.append(file)


def sub_list(t1, t2):
    """
    返回列表t1和列表t2的差集,t1有t2没有的元素
    :param t1:
    :param t2:
    :return:
    """
    t1 = list(t1)
    t2 = list(t2)
    sub_t = [i for i in t1 if i not in t2]
    return sub_t


# 不同时间分辨率下对应的正确命名
# correct_seq_p:平年 correct_seq_r:闰年
# 平年闰年的差异主要体现在monthly上
correct_seq_p = {"8-day": [str(i).zfill(3) for i in range(1, 365, 8)],
                 "16-day": [str(i).zfill(3) for i in range(1, 365, 16)],
                 "monthly": ['001', '032', '060', '091', '121', '152', '182', '213', '244', '274', '305', '335'],
                 "yearly": ["001"]}
correct_seq_r = {"8-day": [str(i).zfill(3) for i in range(1, 365, 8)],
                 "16-day": [str(i).zfill(3) for i in range(1, 365, 16)],
                 "monthly": ['001', '032', '061', '092', '122', '153', '183', '214', '245', '275', '306', '336'],
                 "yearly": ["001"]}

# 第一步:遍历in_folder(包含子文件夹)中所有后缀为.hdf的文件,并将符合要求的文件名存储到列表hdf_files中
in_folder = r"D:\MODIS\MOD16A2" # 修改处1:待检查的文件夹
hdf_files = []
show_files(in_folder, hdf_files)

# 第二步:显示基本信息,文件总数目,各级关键字下对应的文件数目
print("在目录{0}下有.hdf文件数目为{1}个".format(in_folder, len(hdf_files)))
# 产品类型信息:如MYD16A3GF
products = Counter([file.split(".")[0] for file in hdf_files])
print("产品类型:{0}".format(set(list(products.keys()))))
pprint(products.most_common())
print("=" * 20)
# 日期信息:如MYD16A3GF.A2019001
dates = Counter([file.split(".")[1] for file in hdf_files])
print("日期:{0}".format(set(list(dates.keys()))))
pprint(dates.most_common())
print("=" * 20)
# 区块信息:如MYD16A3GF.A2019001.h24v05
tiles = Counter([file.split(".")[2] for file in hdf_files])
print("区块:{0}".format(set(list(tiles.keys()))))
pprint(tiles.most_common())

# 第三步:显示重复文件信息
# 重复项判定原则:若 产品类型、日期、区块均相同则视为重复
print("=" * 40)
names = Counter([".".join(file.split(".")[:3]) for file in hdf_files])
exist_repeat = 0
for i, v in names.items():
    if v > 1:
        exist_repeat = 1
        print("警告:{0}为重复文件!".format(i))
if exist_repeat == 0:
    print("无重复文件")

# 第四步:显示缺失文件信息
# 缺失值判定原则:
# 计算列表相邻元素之间的差,取出现次数最多的为公差
# 以第一项、最后一项为起止项,
current_files = {}  # 当前文件夹中满足条件的文件
missing_files = {}  # 可能缺失的文件
res_type = "8-day"  # 修改处2:当前文件夹的时间分辨率,可选8-day\16-day\monthly\yearly

for file in hdf_files:
    parts = file.split(".")
    index_name = parts[0] + "." + parts[1][:5] + "." + parts[2]  # 键名 = 产品名称 + 区块名
    value_name = parts[1][-3:]
    if index_name in current_files.keys():
        current_files[index_name].append(value_name)
    else:
        current_files[index_name] = []
        current_files[index_name].append(value_name)
print("=============可能缺失的文件为==============")
for i in current_files.keys():
    year = int(i.split(".")[1][1:])
    if year % 4 == 0:
        temp = sub_list(correct_seq_r[res_type], current_files[i])
        if temp:
            missing_files[i] = temp
    else:
        temp = sub_list(correct_seq_p[res_type], current_files[i])
        if temp:
            missing_files[i] = temp
pprint(missing_files)

四、使用例

本代码不依赖于第三方库,只需要配置好python的运行环境,在自带的idle中就可以运行。
in_folder:待检查的文件夹路径
[MODIS数据处理#6]检查大批量下载MODIS数据序列中的重复、缺失文件_第3张图片
res_type:当前文件夹的正确时间分辨率,可选8-day\16-day\monthly\yearly
[MODIS数据处理#6]检查大批量下载MODIS数据序列中的重复、缺失文件_第4张图片

你可能感兴趣的:(MODIS数据处理,python,MODIS)