Python 实践之Pandas 时间数据处理方法详解

news2024/12/27 0:43:36


概要

表格数据中常见的数据类型是数值型(包括整数、浮点数)和字符型,除了这两种数据,时间类型数据也是常见数据的重要组成部分,同时也是数据分析中极其重要的信息。无论是金融领域的股票交易数据,还是企业注册、吊销的微观数据,时间数据都包含了宝贵的信息,掌握时间数据的处理方法可以帮助我们进行数据清洗、筛选、排序、分析等任务。本期我们就来学习如何在 Pandas 中处理时间类型数据。

本教程基于 pandas 1.5.3 版本书写。本文中所有 Python 代码均在集成开发环境 Visual Studio Code (VScode) 中使用交互式开发环境 Jupyter Notebook 中编写,本文分享的代码请使用 Jupyter Notebook 打开。


数据表中的时间数据

常见的数据中,统计数据中的时间大多是日期数据,当然也有不少数据或分析场景中会出现精确到时、分或秒的时间数据,不过一般这些时间数据都规范地存储在表格的数据列中。在计算机中,一个时间点用时间戳(Timestamp)来表示,采用格林威治时间标准,是指从 1970 年 1 月 1 日 0 时 0 分 0 秒起到当下时间点经过的总秒数,是一个庞大的数字。例如时间戳1690181977就代表北京时间 2023 年 7 月 24 日 14 时 40 分左右(可能会受到时区的影响而出现差异),而我们习惯将时间数据存储成年-月-日年-月-日 时:分:秒的格式。由于受到数据文件格式的影响,在 pandas 中经常需要主动将字符型时日期据转换为标准的日期类型,否则当需要根据时间进行筛选和分析时,字符型的日期数据很难参与计算,也非常容易出错。

除了时间类型的应用,时间类型数据在转换时也会遇到各种各样的问题,例如日期中可能包含缺失值、异常值等,下面我们就来学习一下如何解决表格数据中的时间类型问题并进行简单的应用。

读取数据时设置类型

常用的数据类型主要是 Excel 工作表和 csv 数据表,其中  Excel 工作表是二进制文件,能够存储数据的类型,如果其中的时间数据已经事先被设置为日期类型,那么使用 Pandas 读取后日期类型会得到保留,不需要再重新设置数据类型。而 csv 数据表是文本文件,虽然也能够被 Excel / WPS 打开,但文本文件不能保存特殊的数据类型,只能存储字符类型的数据。所以如果要读取 csv 数据表并进行处理,则需要在读取过程中或者读取之后做类型转换。例如现在有一份2021年底清洁生产企业(部分样例数据)的成立与注吊销数据(csv 格式),其中两个字段存储日期数据,如下图所示。

读取数据时能够设置初始字段类型的dtype参数,不过这个参数只能设置整数、浮点数、字符串等常见类型,无法设置日期/时间格式数据,如果希望在读取数据时就设置日期类型,可以在使用pd.read_csv()pd.read_excel()函数时传入参数parse_dates来实现,parse_dates参数可以接收一个列表,将存储日期类型字段的名称存放在这个列表中,就表示 Pandas 在读取数据时会尝试parse_dates中的字段类型解析为标准类型的日期,演示代码如下。

import pandas as pd
# 先使用常规的读取方式
Table = pd.read_csv('./清洁生产企业数据1000条.csv')
# 查看读取后所有字段的类型
Table.dtypes   
'''
企业名称            object
成立日期            object
注(吊)销日期         object
营业状态(2021年底)    object
dtype: object
'''
# 常规读取方式读取后日期字段默认是 object,实际上数据类型为字符型,并不会自动解析为日期类型
# 读取时使用 parse_dates 参数,尝试将日期字段转为标准日期类型
Table = pd.read_csv('./清洁生产企业数据1000条.csv', 
                    parse_dates=['成立日期', '注(吊)销日期'])
# 查看读取后所有字段的类型
Table.dtypes
'''
企业名称                    object
成立日期            datetime64[ns]
注(吊)销日期         datetime64[ns]
营业状态(2021年底)            object
dtype: object
'''
# 使用 parse_dates 参数后,两个存储日期的字段都被解析为标准的日期类型 datetime64[ns]

通过以上代码可以知道,使用pd.read_csv()pd.read_excel()函数时,设置parse_dates参数可以有效地将原本是字符型的日期设置为标准日期类型。不过这样做并不一定会成功,这是因为parse_dates参数的含义是尝试性地将传入的字段解析为标准日期,如果传入的字段中包含不能被转换为标准日期的其他数据,例如数字、非日期格式的字符串,那么这个字段就不会被成功地解析为标准日期,依然保持原来的字段类型。

处理数据时转换为标准日期

如上文所述,在读取数据时通过设置参数可以帮助我们规范数据类型,但那种方式还不能帮我们解决全部的类型问题,例如字段中存在异常值时就无法被解析为标准日期类型。此外,当需要从其他格式的数据文件中读取,或者数据处理中途产生日期字段时,上述方法就不能使用了,此时我们就需要掌握将字符型日期转为标准日期的方式。我们在往期文章Pandas 表格字段类型精讲(含类型转换)中介绍过字段类型转换的操作方式,以上文中读取的演示数据为例,我们再次演示如何将字符型日期转为标准的日期类型,代码如下。

# 不使用 parse_dates 参数,读取后再主动转换类型
Table = pd.read_csv('./清洁生产企业数据1000条.csv')
# 使用两种不同的方式将两个字段转为标准日期类型
Table['成立日期'] = Table['成立日期'].astype('datetime64[ns]')    # 方式 1,使用 Series.astype() 函数
Table['注(吊)销日期'] = pd.to_datetime(Table['注(吊)销日期']) # 方式 2,使用 pd.to_datetime() 函数
# 查看转换类型后的数据
Table

如上图所示,字段注(吊)销日期中存在空值,该字段中的空值表示企业的死亡日期(截至 2021 年底),没有死亡的企业不存在注吊销日期。经过转换后,数据中的空值NaN变为NaTNaT(not a time)是 Pandas 中的时间空值,可以被表示为 pd.NaT,我们可以把它理解为一个不表示任何时间点的时间数据,同时,任何时间点与NaT进行比较和计算都会得到 False,这一点和NaN(np.NaN)非常相似。

有的数据中可能会包含异常的日期数据,比如010-08-062010-13-022002-2-30,类似的异常数据会给我们的数据处理带来非常多的麻烦。这里我们手动将演示数据中的几个日期修改为异常日期,生成一个含有异常日期的数据副本,接下来将会演示如何识别和处理异常的日期数据。

## 异常日期存储在 成立日期 字段中的前三年行
# 读取含有异常日期的数据
Table = pd.read_csv('./清洁生产企业数据1000条_ERROR.csv', 
                    parse_dates=['成立日期', '注(吊)销日期'])
# 查看读取后所有字段的类型
Table.dtypes
'''
企业名称                    object
成立日期                    object
注(吊)销日期         datetime64[ns]
营业状态(2021年底)            object
dtype: object
'''
# 如上文所述,当字段中存在异常的日期数据时,即使使用 parse_dates 参数指定了该字段,也不会有实际效果

Table   # 查看数据

 Pandas 中默认的时间/日期类型是由pd.Timestamp()函数转换的来的,该函数能够表示的时间范围是1678-01-01 00:00:00——2262-04-11 23:47:16,因此不在此时段内的时间数据都会被视作异常值。而 Python 中的标准库datetime下的datetime.datetime()函数也可以进行时间/日期转换,支持的时间范围是0001-01-01 00:00:00——9999-12-31 23:59:59(注意即使是公元 1 年,也必须是四位数字)。无论使用哪种方式,都不允许出现 13 月、2 月 30 日这种绝对错误的日期。

当数据中出现异常的日期数据时,设置parse_dates参数来解析日期字段的方式不再奏效,但依然可以通过 Pandas 的类型转换函数来处理,即使用Series.astype()pd.to_datetime()函数来实现。但是如果继续像上文中那样直接进行类型转换也会报错,因为默认的转换方式是将字段中的每一个值都转为日期类型,由于字段中包含错误的日期,所以转换时会报错。这时我们可以借助pd.to_datetime()函数中用于控制解析错误处理方式的参数errors来达到目的,示范代码如下。

# 使用 pd.to_datetime 转换日期时,设置参数 errors='coerce',
# 表示类型转换过程中将错误的时间替换为时间空值 NaT
Table['成立日期'] = pd.to_datetime(Table['成立日期'], errors='coerce')
# 查看错误的时间(前三行都是错误的时间)转换后的结果
print(Table['成立日期'][1])      # NaT  (空时间类型)
# 查看正确的时间转换后的结果
print(Table['成立日期'][100])    # 2014-04-25 00:00:00   (正常时间类型)

在专门用来将字符日期字段转换为标准日期类型字段pd.to_datetime()函数中,参数errors的作用是控制函数在遇到异常日期(包括错误日期和规定范围之外的日期)时的处置方法,它的默认值是'raise',表示遇到异常日期时报错;也可以设置为'ignore',表示尝试性地将字段设置为日期类型,如果字段中包含异常日期,那么转换不会成功,但也不会报错,注意'ignore'的机制不是将正确的日期转换以及保留异常的日期,而是出现异常日期时不会对字段内任何日期做转换;上述代码使用的参数值为'coerce',这是pd.to_datetime()函数中errors参数独有的可选值(astype()函数也有errors参数,但没有'coerce'选项),表示类型转换过程中将错误的时间替换为时间空值NaT。了解这个机制更有助于我们选择是否使用该参数值,避免数据丢失。

如果你的数据中包含1678年之前或2262之后的日期,那么这就跳出了 Pandas 默认能够接受的时间范围,出现这种情况时,我们可以放弃使用 Pandas 提供的日期转换函数,改用标准库 datetime 中的函数进行日期转换,当然这可能比较麻烦。老规矩,我们先将成立日期字段中前三行数据修改为不受 Pandas 支持的日期,当然这样修改后的数据不符合数据逻辑和真实性,但我们只是为了演

示操作方式而已,代码如下。

# 先读取含有规定范围之外日期的数据,注意年份一定得是四位数字
Table = pd.read_csv('./清洁生产企业数据1000条_OUT.csv')
Table    # 查看数据,此时成立日期字段为字符型

 

# 将日期转换为 datetime 库中的日期类型
from datetime import datetime
# 定义日期转换函数
def Transform_date(str_date):
    # 要求是 year-month-day 格式的日期,也可根据具体数据做调整
    date = datetime.strptime(str_date, '%Y-%m-%d')
    return date
# 应用上面定义的日期转换函数进行类型转换
Table['成立日期'] = Table['成立日期'].apply(Transform_date)
# 查看转换后字段内数据值的类型
print(type(Table['成立日期'][2]))   # <class 'datetime.datetime'>
print(type(Table['成立日期'][10]))  # <class 'datetime.datetime'>
# 转换后字段类型仍未 object,但是内部的数据已经被转为标准的日期,可以正常地进行排序、筛选、分析等操作
Table        # 最后查看数据

 

表格中日期类型的基本使用

1根据日期排序

结构化数据的基本分析中,当涉及到日期数据时,在转换为标准日期类型之后就可以方便地进行筛选排序等操作了。例如可以根据成立日期对数据做降序排序,代码如下。

# 默认升序排序,ascending=False 表示降序
Table_sort = Table.sort_values(by='成立日期', ascending=False)
Table_sort

2根据日期筛选

当然也可以根据日期筛选出符合要求的数据,例如可以筛选出成立日期在 2000 年 10 月 1 日 之前的企业数据,不过这样做需要先创建一个时间点/日期,然后才可以和数据中的成立日期进行对比。在 Python 中创建时间点非常简单,这里介绍两种方式,代码如下。

# 创建时间点/日期的两种方式
# 方式 1,使用 pd.Timestamp() 函数
date1 = pd.Timestamp(2000, 10, 1)
print(date1)               # 2000-10-01 00:00:00
# 方式 2,使用 datetime.datetime() 创建
from datetime import datetime   # 实际上上文已经导入
date2 = datetime(2000, 10, 1)
print(date2)               # 2000-10-01 00:00:00

虽然两种方式创建的日期类型不是同一标准,但是相互之间仍可以进行正常的比较和运算。无论哪种日期类型数据,都有以下几个通用的属性,通过属性我们可以从日期中取出对应的信息,有时根据这些信息就可以进行基本的处理和分析,下面是时间/日期类型常见的属性。

## 时间/日期类型的常见属性
# 先创建时间点:2000 年 10 月 1 日 中午 12 时 30 分 59 秒
date3 = pd.Timestamp(2000, 10, 1, 12, 30, 59)  
# 年 属性
print(date3.year)             # 2000
# 月 属性
print(date3.month)            # 10
# 日 属性
print(date3.day)              # 1
# 小时 属性
print(date3.hour)             # 12
# 分钟 属性
print(date3.minute)           # 30
# 秒 属性
print(date3.second)           # 59
# 周几
print(date3.dayofweek)        # 6
# 该年第几周
print(date3.weekofyear)       # 39
# 该年的第几天
print(date3.dayofyear)        # 275
# 当年是否闰年
print(date3.is_leap_year)     # True
# 当月总天数
print(date3.days_in_month)    # 31
# 哪个季度
print(date3.quarter)          # 4

时间点创建后,可以开始筛选数据了,筛选的代码如下。

# 筛选出成立日期在 2000 年 10 月 1 日 之前的企业数据
date1 = pd.Timestamp(2000, 10, 1)
# 开始筛选
Table_before2000 = Table[Table['成立日期'] < date1]
Table_before2000      # 查看筛选结果

 

3时长数据计算

除了时间的排序和筛选,Pandas 还提供了比较有特色的时间差类型数据值,可以满足我们更加多元的数据分析。例如当分析样例数据中企业的平均存活时间就需要用到时间差(时长)数据,两个日期之间可以进行比较和相减,比较会得到比较结果 True 或 False;而相减则会得到一个时长数据,这个时长数据以日、时、分、秒为单位,为什么不是以年、月来做单位呢,这样不是更方便分析计算吗?实际上这是因为一年或一月的时长是不固定的,存在闰年、闰月的现象。下面是演示代码。

## 先创建两个时间点
date3 = pd.Timestamp(2000, 10, 1, 12, 30, 59)
date4 = pd.Timestamp('now')      # 当前时间点:2023-07-26 11:24:58
# 计算时间差,得到时长数据
timedelta = date4 - date3
# 查看时间差
timedelta      # Timedelta('8332 days 22:53:59')

也可以直接根据字段进行计算,例如注(吊)销日期字段与成立时间字段相减就可以得到一个正值时长数据,反之将得到负值时长数据,下面是计算企业存活时长的代码。

# 读取时正确的样例数据(不存在脏数据的)
Table = pd.read_csv('./清洁生产企业数据1000条.csv', parse_dates=['成立日期', '注(吊)销日期'])
# 在合适的位置插入一列空值
Table.insert(3, '存活时间', '')
# 将两个字段做差,得到的序列赋值给刚刚创建的新字段
Table['存活时间'] = Table['注(吊)销日期'] - Table['成立日期']
Table   # 查看数据

 

数据中未死亡企业的注(吊)销日期为空,这是正常现象,此处的计算也可以佐证上文的描述,即空日期 NaT 与任何日期数据进行计算都会得到 NaT 本身。运算后就可以得到每个企业的存活时间,进而分析样例数据中企业的平均存活时间了,分析代码如下。

# 先检验是否存在异常数据,即存活时间为 0 或负值的
Error_data = Table[Table['存活时间'] <= pd.Timedelta(0)]
Error_data

 

发现其中三条数据注册当天就注吊销了,这里我们将其视作脏数据进行清除。

# Error_data.index 表示脏数据 Error_data 的索引值
Table.drop(Error_data.index, inplace=True)

最后在计算企业的平均存活时间。

import datetime      # 导入 datetime 库用于做时长转换
# 先筛选出存活时长不为空的数据,即已经死亡的企业,且不是异常值的
Dead_data = Table[Table['存活时间'].notna()]
# 所有死亡企业的存活时长转为以秒为单位的时长,然后加总,
TimeSeries = Dead_data['存活时间'].dt.total_seconds()
Total_seconds = TimeSeries.sum()
# 再换算成以天为单位的时长,因为 pd.Timestamp() 支持的时长太小了,所以才转换
Total_days = datetime.timedelta(seconds=Total_seconds)
# 再除以企业数量,得到平均存活时长
Mean_survival_time = Total_days / Dead_data.shape[0]
Mean_survival_time       # datetime.timedelta(days=3814, seconds=69189, microseconds=537223)

最后计算出样例数据中 497 个清洁生产企业(已经死亡的)的平均存活时间约为 3814 天,按一年 365 天计算,每个企业的平均存活时间为 10.4 年。

通过以上代码我们也可以知道,可以使用pd.Timedelta()函数来创建时长数据,例如pd.Timedelta(0)就表示时长为 0 的时长数据,使用pd.Timedelta()创建时长数据的基本用法如下。

# pd.Timedelta()创建时长数据的基本用法

# 一天
pd.Timedelta('1D')           # Timedelta('1 days 00:00:00')
# 两周
pd.Timedelta('2W')           # Timedelta('14 days 00:00:00')
# 3天4小时5分钟6秒
pd.Timedelta('3d4h5m6s')     # Timedelta('3 days 04:05:06')

同时,时长数据也可以进行加、减、乘、除等基础运算,不过 Pandas 支持的运算范围很小,所以上文中的代码在计算时长时先将以天为最大单位的 pd.Timedelta 数据转换为以秒为单位的 datetime.timedelta 数据后才得以进行下去。

以上就是本期文章介绍的所有关于日期/时间数据的基本处理方式啦。

总结

本期文章介绍了 Pandas 中处理日期数据的方法,包括数据类型的解析与转换,日期类型的排序、筛选、计算等方法。在 Pandas 中,无论是日期的范围,还是时长的范围都还不够大,当默认的范围无法解决问题时,最好要学会使用 Python 标准库 datetime 来做补充。常见的面板数据中,日期或时间是非常重要的信息,掌握日期类型的转换和用法是每一个数据人必备的基本技能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/954063.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

恒运资本:a股总市值怎么看?

跟着经济开展和金融商场的壮大&#xff0c;投资者越来越重视股市的行情。而对于A股商场来说&#xff0c;总市值是一个非常重要的目标。那么&#xff0c;A股总市值怎么看&#xff1f;以下是本文的详细剖析。 一、A股总市值界说与核算方法 首要需要了解A股总市值的界说和核算方法…

深度了解BSP452芯片特性与应用|百能云芯

在现代科技领域&#xff0c;芯片是推动各种电子设备发展的核心。BSP452作为一款重要的芯片&#xff0c;具有广泛的应用领域和独特的特性&#xff0c;为多个领域的创新提供了支持。百能云芯将深入探讨BSP452芯片的特点、应用领域以及未来发展前景。 BSP452芯片是一款N沟道MOS场效…

详细对比超融合服务器硬件平滑升级方案:新建集群 VS 滚动升级

作者&#xff1a;深耕行业的金融团队 刘慧敏 在企业 IT 基础架构运维中&#xff0c;经常会遇到以下问题&#xff0c;从而需要对服务器硬件进行更换或升级&#xff1a; 服务器达到维护期限&#xff1a;通常在金融行业中&#xff0c;生产环境的服务器维护期限在 5 年左右&#…

【进程间通信】管道

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

基于RabbitMQ的模拟消息队列需求文档

文章目录 一、项目背景二、需求分析1.核心概念2.BrokerServer核心组件3.核心API4.交换机类型5.持久化6.网络通信7.消息应答 三、消息队列模块划分 一、项目背景 什么是消息队列&#xff1f; 消息队列就是&#xff0c;基于阻塞队列&#xff0c;封装成一个独立的服务器程序&#…

springboot实战(一)之项目搭建

环境准备 ideajdk1.8springboot版本 2.7.15 项目开始 1.打开idea&#xff0c;点击new project 2.选择spring initillizr 核对&#xff1a;Server Url是否是&#xff1a;start.spring.io&#xff0c;然后根据自己依次设置项目名称、存储位置和包名&#xff0c;如下&#xff…

洛朗展式求留数方法计算超越函数f(x)=e^(cosx)的定积分

https://math.stackexchange.com/questions/2468863/what-is-the-integral-of-e-cos-x https://tieba.baidu.com/p/6881253594 例子 https://www.zhihu.com/question/441124046/answer/1697123609?utm_id0

《Kubernets证书篇:kubernetes1.24.17证书修改时间限制》

一、背景 Kubernetes 默认的证书有效期只有1年,因此需要每年手动更新一次节点上面的证书,特别麻烦而且更新过程中可能会出现问题,因此我们要对 Kubernetes 的 SSL 证书有效期进行修改,这里将证书的时间限制修改为100年。 环境信息如下: 操作系统内核版本K8S版本Ubuntu 20.…

百度的AI画图和讯飞的AI画图目前就这样了

今天接到百度的短信&#xff0c;说给我一个搜索AI的测试权限&#xff0c;心血来潮&#xff0c;让AI给我做个画&#xff0c;百度和讯飞来做个PK&#xff0c;结果都不敢恭维哈&#xff0c;双方都有待提高&#xff0c;加油&#xff01;

代码解读 FCOS网络(基于mmrotate框架)

文章目录 1. rotated_fcos_head.py1.1 __init__函数1.2 forward_single 函数1.2.1 父类的forward_single 函数&#xff08;anchor_free_head.py&#xff09;1.2.2 _init_layers 函数 1.3 loss 函数1.3.1 get_targets 函数1.3.1.1 _get_target_single 函数 1.3.2 prior_generato…

vr城乡规划建筑设计元宇宙平台提高工作协同效率

随着科技的发展&#xff0c;元宇宙正逐渐渗透到各个行业领域中&#xff0c;特别是建筑设计&#xff0c;那么在建筑设计中&#xff0c;利用元宇宙平台有哪些特点及优势呢? 面对建筑行业日益突出的高消耗、高风险、高投入、低利润的问题&#xff0c;如何提升企业经营管理水平&am…

Python Pyecharts 制图

基本图表 - pyecharts - A Python Echarts Plotting Library built with love. from pyecharts import options as opts from pyecharts.charts import Pie from pyecharts.faker import Fakerc (Pie().add("",[list(z) for z in zip(["7室1厅", "5…

基于KNN算法的鸢尾花种类预测

K近邻法算法思想 K近邻法&#xff08;K-Nearest Neighbor&#xff0c;KNN&#xff09;是一种基本的分类和回归方法&#xff0c;是监督学习方法里的一种常用方法。K近邻算法用一句通俗的古语来说就是&#xff1a;“物以类聚&#xff0c;人以群分”。有人说看一个人什么样&#…

【Unity3D游戏魔坦之争】游戏结束流程封装实现【七】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

虹科分享 | 温度边缘效应对冻干成品含水量的影响(下)——优化和总结

上一篇文章中介绍到借助虹科Ellab的温度记录仪观察到由于冻干机壁面温度的影响&#xff0c;形成的边缘效应导致同一隔板的不同区域冻干饼块的干燥程度不均匀&#xff0c;含水量不同。 06 初次试验结果&#xff1a; 二次干燥中的产品温度显示&#xff1a; 放置在搁板中间的产品…

Linux内核源码分析 (A)常见内核面试题

Linux内核源码分析 (A)常见内核面试题 文章目录 Linux内核源码分析 (A)常见内核面试题调用 schedule() 进行进程切换的方式有几种CFS调度器vruntime的计算方式 网站收集面试题集合1 调用 schedule() 进行进程切换的方式有几种 系统调用 do_fork()&#xff1a;copy_process()定…

供热管网安全运行监测,提升供热管网安全性能

城市管网是城市的“生命线”之一&#xff0c;是城市赖以生存和发展的基础&#xff0c;在城市基础设施高质量发展中发挥着重要作用。供热管网作为城市生命线中连接供热管线与热用户的桥梁&#xff0c;担负着向企业和居民用户直接供热的重要职责。随着城市热力需求的急剧增加&…

【SpringBoot】Swagger和knife4j的使用

文章目录 前言1.什么是Swagger和Knife4j2.Swagger和Knife4j怎么用2.1 引入依赖2.2 设置配置类2.3 启动验证 3.完结撒花 前言 springboot笔记集合: springboot笔记合计 没用的废话理论不多说&#xff0c;会用就完了 1.什么是Swagger和Knife4j Swagger是一种开源的API描述语言…

ranger无法同步用户问题解决

1.首先就是定位日志,日志目录 cd /var/log/ranger/usersync 定位到问题报错如下: LdapDeltaUserGroupBuilder.getUsers() failed with exception:java.naming.AuthticationExceptiom :[LDAP:error code 49 - Invalid Credentials]:remaing name ‘ouPeople,dc*.dccom’ 解决办法…

frida动态调试入门01——定位关键代码

说明 frida是一款Python工具可以方便对内存进行hook修改代码逻辑在移动端安全和逆向过程中常用到。 实战 嘟嘟牛登录页面hook 使用到的工具 1&#xff0c;jadx-gui 2&#xff0c;frida 定位关键代码 使用jadx-gui 进行模糊搜索&#xff0c;例如搜索encyrpt之类的加密关键…