Python使用多线程操作tif影像和HBase数据库

这篇具有很好参考价值的文章主要介绍了Python使用多线程操作tif影像和HBase数据库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文介绍使用Python的多线程技术,提高happybase模块和gdal模块的效率,从tif格式的影像文件中读取数据,并将其存储到HBase数据库中。主要步骤包括:

  • 准备工作:安装Python环境,安装happybase模块和gdal模块,安装HBase数据库,并准备tif影像文件。
  • 读取tif影像数据:使用readTif函数读取tif影像数据集,并获取其宽度、高度、波段数、数据数组、仿射变换参数和投影信息。遍历tif影像文件所在的文件夹,获取tif影像文件的日期和分块信息。
  • 写入HBase数据库:创建一个happybase连接对象,并获取或创建一个happybase表对象。遍历每个分块,使用readTif函数读取每个分块的每个日期的每个波段的数据,并将其存储到一个三维的numpy数组中。遍历每个像素,将其对应的每个波段的每个日期的数据组合成一个字典,作为HBase表中的列值。使用分块编号、行号和列号拼接成一个字符串,作为HBase表中的行键。使用put方法将行键和列值写入HBase表中。关闭happybase连接对象。
  • 使用多线程技术:导入threading模块,创建一个信号量对象,用于限制线程的最大数量。遍历每个分块,使用信号量对象的acquire方法获取一个信号量,然后创建一个新的线程对象,并指定目标函数为load函数,以及传递分块编号、分块列表和日期列表作为参数。然后调用start方法启动该线程。在load函数中,在完成数据的读取和写入后,使用信号量对象的release方法释放一个信号量,并关闭happybase连接对象。记录程序运行的开始时间和结束时间,并计算程序运行的总时间。

一、环境准备

  • 安装Python环境,本文使用的是Anaconda3。
  • 安装happybase模块,可以使用pip或conda命令。例如:
pip install happybase
  • 安装gdal模块,可以使用pip或conda命令。例如:
conda install gdal
  • 启动分布式集群,hadoop以及hbase;启动thrift服务,可以使用hbase-daemon.sh脚本。例如:
hbase-daemon.sh start thrift

就可以使用happybase模块连接到thrift服务,并操作HBase数据库了 

  • 准备tif格式的影像文件,并放在一个文件夹中。本文使用的是Sentinel-2卫星的10个波段的影像数据,分为多个日期和多个分块。

Python使用多线程操作tif影像和HBase数据库

二、定义读取tif影像数据的函数

  • 导入需要的模块,包括time、happybase、gdal、numpy、pandas、os、tqdm和threading。例如:
import time
import happybase
from osgeo import gdal
import numpy as np
import pandas as pd
import os
from tqdm import tqdm
import threading
  • 定义一个函数readTif,用于读取tif格式的影像数据集,并返回其宽度、高度、波段数、数据数组、仿射变换参数和投影信息。例如:
#  读取tif数据集
def readTif(fileName, xoff=0, yoff=0, data_width=0, data_height=0):
    dataset = gdal.Open(fileName)
    num_bands = dataset.RasterCount
    # print(num_bands)
    if dataset == None:
        print(fileName + "文件无法打开")
    #  栅格矩阵的列数
    width = dataset.RasterXSize
    #  栅格矩阵的行数
    height = dataset.RasterYSize
    #  波段数
    bands = dataset.RasterCount
    #  获取数据
    if (data_width == 0 and data_height == 0):
        data_width = width
        data_height = height
    data = dataset.ReadAsArray(xoff, yoff, data_width, data_height)
    #  获取仿射矩阵信息
    geotrans = dataset.GetGeoTransform()
    #  获取投影信息
    proj = dataset.GetProjection()
    return width, height, bands, data, geotrans, proj
  •  获取tif影像文件所在的文件夹路径,并遍历该文件夹下所有以.tif为后缀名的文件。例如:
# 分块影像所在文件夹,不能有中文
tifDir = r"E:\pyimg\tif2csv\S2SR10mallband3tile"
tifs = [i for i in os.listdir(tifDir) if i.endswith(".tif")]
print("有 %s 个tif文件" % len(tifs))
  •  获取tif影像文件的日期和分块信息,并去重排序。例如:
# 获取目标文件数量,前缀相同的
bandlist=['B2','B3','B4','B5','B6','B7','B8','B8A','B11','B12']
datelist1 = []
fenkuailist1 = []
for i in tifs:
    datelist1.append(i[:-26])
    fenkuailist1.append(i[-25:-4])

datelist = list(set(datelist1))
datelist.sort(key=datelist1.index)
fenkuailist = list(set(fenkuailist1))
fenkuailist.sort(key=fenkuailist1.index)
print("有 %s 个日期" % len(datelist))
print("datelist" , datelist)
print("每个日期 %s 个块" % len(fenkuailist))
print("fenkuailist" , fenkuailist)

三、创建happybase连接和表对象

  • 创建一个happybase连接对象,并指定HBase数据库的IP地址。例如:
connection = happybase.Connection('192.168.1.100')
# # before first use:
connection.open()
  • 获取或创建一个happybase表对象,并指定表名和列族名。例如:
table = connection.table('rawdata')

四、定义写入HBase数据库的函数

  • 定义一个函数load,用于读取和写入一个分块的数据。该函数接受分块编号、分块列表和日期列表作为参数。该函数的主要步骤如下:文章来源地址https://www.toymoban.com/news/detail-494494.html

    • 打印当前分块的编号。
    • 初始化一个三维的numpy数组,用于存储该分块的所有波段和所有日期的数据。
    • 遍历每个日期,使用readTif函数读取该分块的每个日期的每个波段的数据,并将其存储到numpy数组中。
    • 打印写入中的提示。
    • 遍历每个像素,将其对应的每个波段的每个日期的数据组合成一个字典,作为HBase表中的列值。使用分块编号、行号和列号拼接成一个字符串,作为HBase表中的行键。使用put方法将行键和列值写入HBase表中。
    • 关闭happybase连接对象。
def load(kuai,fenkuailist,datelist):
        connection = happybase.Connection('192.168.1.100')
        # # before first use:
        connection.open()
        table = connection.table('rawdata')
        
        print("(%d/%d)块编号:"%(kuai+1,len(fenkuailist)),fenkuailist[kuai])
        # 初始化立方体
        img_file = tifDir + "\\" + datelist[0] + "-" + fenkuailist[kuai] + ".tif"
        im_width, im_height, im_bands, im_data, kuai_im_geotrans, kuai_im_proj = readTif(img_file)

        tmpttt = np.empty((im_bands, im_width * im_height, len(datelist)))
    # print("波段 %s 个" % im_bands)
    # print("行列数", im_width, im_height)
        for shijian in range(len(datelist)):
        #  图像
            img_file = tifDir + "\\" + datelist[shijian] + "-" + fenkuailist[kuai] + ".tif"
            # print(img_file)
            im_width, im_height, im_bands, im_data, im_geotrans, im_proj = readTif(img_file)
            kuai_im_geotrans = im_geotrans
            kuai_im_proj=im_proj

            for j in range(im_bands):
                tmpttt[j, :, shijian] = im_data[j].flatten(order='C')
        print("写入中...")
        for index in tqdm(range(im_width * im_height)):
            dt={}
            for ban in range(im_bands):
                d1=zip(map(lambda  x:"f1:"+x+bandlist[ban],datelist),tmpttt[ban, index, :].astype(str))
            # Converting zip object to dict using dict() contructor.
                dt.update(d1)
            key=str(kuai%3)+fenkuailist[kuai][6:10]+fenkuailist[kuai][-4:]+str(index)
            table.put(key, dt)  # 提交数据,0001代表行键,写入的数据要使用字典形式表示
        connection.close()  # 关闭传输

五、使用多线程技术

  • 导入threading模块,该模块提供了多线程的支持,可以创建和管理线程,以及实现线程间的同步和通信。
  • 使用time模块的perf_counter函数,记录程序运行的开始时间。例如:
# #计时开始
start = time.perf_counter()
  • 使用threading模块的Semaphore类,创建一个信号量对象,用于限制线程的最大数量。信号量对象有一个内部计数器,每当一个线程调用acquire方法时,计数器减一,每当一个线程调用release方法时,计数器加一。如果计数器为零,那么acquire方法将阻塞,直到其他线程调用release方法。例如:
sem=threading.Semaphore(5) #限制线程的最大数量为5
  • 遍历每个分块,使用sem对象的acquire方法获取一个信号量,然后使用threading模块的Thread类,创建一个新的线程对象,并指定目标函数为load函数,以及传递分块编号、分块列表和日期列表作为参数。然后调用start方法启动该线程。例如:
for kuai in range(30,72):
    sem.acquire()
    threading.Thread(target = load, args = (kuai,fenkuailist,datelist)).start()
  • 在load函数中,在完成数据的读取和写入后,使用sem对象的release方法释放一个信号量,并关闭happybase连接对象。例如:
def load(kuai,fenkuailist,datelist):
        connection = happybase.Connection('192.168.1.100')
        # # before first use:
        connection.open()
        table = connection.table('rawdata')
        
        print("(%d/%d)块编号:"%(kuai+1,len(fenkuailist)),fenkuailist[kuai])
        # 初始化立方体
        img_file = tifDir + "\\" + datelist[0] + "-" + fenkuailist[kuai] + ".tif"
        im_width, im_height, im_bands, im_data, kuai_im_geotrans, kuai_im_proj = readTif(img_file)

        tmpttt = np.empty((im_bands, im_width * im_height, len(datelist)))
    # print("波段 %s 个" % im_bands)
    # print("行列数", im_width, im_height)
        for shijian in range(len(datelist)):
        #  图像
            img_file = tifDir + "\\" + datelist[shijian] + "-" + fenkuailist[kuai] + ".tif"
            # print(img_file)
            im_width, im_height, im_bands, im_data, im_geotrans, im_proj = readTif(img_file)
            kuai_im_geotrans = im_geotrans
            kuai_im_proj=im_proj

            for j in range(im_bands):
                tmpttt[j, :, shijian] = im_data[j].flatten(order='C')
        print("写入中...")
        for index in tqdm(range(im_width * im_height)):
            dt={}
            for ban in range(im_bands):
                d1=zip(map(lambda  x:"f1:"+x+bandlist[ban],datelist),tmpttt[ban, index, :].astype(str))
            # Converting zip object to dict using dict() contructor.
                dt.update(d1)
            key=str(kuai%3)+fenkuailist[kuai][6:10]+fenkuailist[kuai][-4:]+str(index)
            table.put(key, dt)  # 提交数据,0001代表行键,写入的数据要使用字典形式表示
        connection.close()  # 关闭传输
        sem.release()
  • 使用time模块的perf_counter函数,记录程序运行的结束时间,并计算程序运行的总时间。例如:
# #计时结束
delta = time.perf_counter()-start
print("程序运行的时间是:{}秒".format(delta))

到了这里,关于Python使用多线程操作tif影像和HBase数据库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SQLITE_BUSY 是指 SQLite 数据库返回的错误码,表示数据库正在被其他进程或线程使用,因此当前操作无法完成。

    当多个进程或线程同时尝试对同一个 SQLite 数据库进行写操作时,就可能出现 SQLITE_BUSY 错误。这是为了确保数据库的数据完整性和一致性而设计的并发控制机制。 如果你在使用 SQLite 时遇到 SQLITE_BUSY 错误,可以考虑以下解决方法: 重试操作:在捕获到 SQLITE_BUSY 错误后,可以

    2024年02月09日
    浏览(36)
  • 基于pyqt5+opencv实现16位tif影像转jpg

    现在大部分图像软件都支持tiff影像的浏览,但都是仅限于8位的影像,对应CV16U类型的tiff影像并不支持(这需要专业的gis软件才可进行操作)。为了便捷操作,故此基于pyqt5+opencv实现16位tif影像转jpg的软件。 本博文涉及基于ui文件直接构建界面、实现文件拖拽打开、按钮组状态

    2024年02月12日
    浏览(31)
  • Python读取hbase数据库

    1. hbase连接 首先用hbase shell 命令来进入到hbase数据库,然后用list命令来查看hbase下所有表,以其中表“DB_level0”为例,可以看到库名“baotouyiqi”是拼接的,python代码访问时先连接: 备注:完整代码在最后,想运行的直接滑倒最后复制即可 2. 按条件读取hbase数据 然后按照条件

    2024年04月09日
    浏览(39)
  • python——数据库操作PyMysql使用详解

    劝君惜取少年时 在编写小脚本时,PyMysql是快速连接并操作数据库的一个不错选择。 连接数据库 使用connect函数创建连接对象,此连接对象提供关闭数据库、事务回滚等操作 一般传参为:host, user, password, port(默认为3306), database(想要连接的数据库名) 连接对象的常见方法 :

    2024年02月02日
    浏览(45)
  • 零基础学Python|Python高阶-使用Python操作数据库

    ​ 作者主页:编程指南针 作者简介:Java、前端、Python开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发、毕业设计开发、面试技术整理、最新技术分享 收藏点赞不迷路 关注作者有好处 文末获得源码 数据库作为存储系统数据的主要工具,担负着数据持久化存

    2024年02月10日
    浏览(28)
  • 使用IDEA连接hbase数据库

     Hbase是安装在另一台LINUX服务器上的,需要本地通过JAVA连接HBase数据库进行操作。由于是第一次接触HBase,过程当中百度了很多资料,也遇到了很多的问题。耗费了不少时间才成功连接上。特记录下过程当中遇到的问题。 JAVA连接HBase代码如下: 首先通过POM将需要的JAR包导入。

    2024年02月03日
    浏览(76)
  • Python 操作 MySQL:使用 mysql-connector-python 操作 MySQL 数据库

    大家好,我是水滴~~ 当涉及到使用 Python 操作 MySQL 数据库时, mysql-connector-python 库是一个强大而常用的选择。该库提供了与 MySQL 数据库的交互功能,使您能够执行各种数据库操作,如连接数据库、执行查询和插入数据等。在本文中,我们将介绍如何使用 mysql-connector-python 库来

    2024年02月04日
    浏览(36)
  • 【100天精通python】Day30:使用python操作数据库_数据库基础入门

     专栏导读  专栏订阅地址: https://blog.csdn.net/qq_35831906/category_12375510.html 1.1 什么是数据库?         数据库是一个结构化存储和组织数据的集合,它可以被有效地访问、管理和更新。数据库的目的是为了提供一种可靠的方式来存储和管理大量的数据,以便用户和应用程序

    2024年02月13日
    浏览(45)
  • python3使用pymsql操作mysql数据库

    操作系统 :Windows 10_x64 python版本 :3.9.2 pymysql版本: 1.0.2 MySQL版本: 5.7.38   之前写过一篇关于python操作mysql数据库的文章: https://www.cnblogs.com/MikeZhang/p/pythonOptMysql20170703.html 当时是基于python 2.7 和 mysql 5.5来整理的,但目前python 2.7已经不再维护,主流的是python 3,今天基于pyt

    2024年02月05日
    浏览(45)
  • Python 操作 MySQL 数据库:使用 mysql-connector-python 库

    在现代应用程序中,与数据库的交互是不可或缺的一部分。Python 提供了许多库来连接和操作各种数据库,其中最常用的之一就是 mysql-connector-python 。本篇博客将介绍如何使用 Python 操作 MySQL 数据库,包括连接数据库、创建表、插入数据、查询数据以及更新和删除数据等操作。

    2024年02月03日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包