机器学习---决策树分类代码

1. 计算数据集的香农熵

from numpy import *  
import numpy as np  
import pandas as pd  
from math import log  
import operator  #计算数据集的香农熵  
def calcShannonEnt(dataSet):  numEntries=len(dataSet)  labelCounts={}  #给所有可能分类创建字典  for featVec in dataSet:  currentLabel=featVec[-1]  if currentLabel not in labelCounts.keys():  labelCounts[currentLabel]=0  labelCounts[currentLabel]+=1  shannonEnt=0.0  #以2为底数计算香农熵  for key in labelCounts:  prob = float(labelCounts[key])/numEntries  shannonEnt-=prob*log(prob,2)  return shannonEnt  

香农熵公式: 

数据集: 

2. 对离散变量划分数据集 

#对离散变量划分数据集,取出该特征取值为value的所有样本  
def splitDataSet(dataSet,axis,value):  retDataSet=[]  for featVec in dataSet:  if featVec[axis]==value:  reducedFeatVec=featVec[:axis]  reducedFeatVec.extend(featVec[axis+1:])  retDataSet.append(reducedFeatVec)  return retDataSet  

这个函数用于划分数据集。它的作用是从给定的数据集中,根据指定的特征和取值,提取出符合条

件的样本集合。函数的输入参数包括数据集(dataSet)、特征的索引(axis)和特征取值

(value)。在函数内部,通过遍历数据集中的每个样本(featVec),判断该样本在指定特征上的

取值是否与给定的取值相等。如果相等,则将该样本添加到结果集合(retDataSet)中。为了将样

本添加到结果集合中,需要先创建一个新的样本(reducedFeatVec),它是将原样本中指定特征

的取值去除后的结果。具体做法是通过切片操作将特征索引之前和之后的部分合并起来,形成新的

样本。最后,将新样本添加到结果集合中。最后,函数返回结果集合(retDataSet),其中包含了

所有符合条件的样本。

3. 对连续变量划分数据集

#对连续变量划分数据集,direction规定划分的方向,  
#决定是划分出小于value的数据样本还是大于value的数据样本集  
def splitContinuousDataSet(dataSet,axis,value,direction):  retDataSet=[]  for featVec in dataSet:  if direction==0:  if featVec[axis]>value:  reducedFeatVec=featVec[:axis]  reducedFeatVec.extend(featVec[axis+1:])  retDataSet.append(reducedFeatVec)  else:  if featVec[axis]<=value:  reducedFeatVec=featVec[:axis]  reducedFeatVec.extend(featVec[axis+1:])  retDataSet.append(reducedFeatVec)  return retDataSet  

这是一个用于划分连续变量数据集的函数。它接受四个参数:dataSet(数据集),axis(要划分

的特征的索引),value(划分的阈值),direction(划分的方向)。函数的作用是根据给定的方

向和阈值,将数据集划分为两个子集。如果direction为0,则将大于阈值的样本划分到一个子集

中;如果direction不为0,则将小于等于阈值的样本划分到一个子集中。

在函数的实现中,通过遍历数据集中的每个样本,根据给定的方向和阈值进行划分。如果样本的特

征值大于阈值且方向为0,将该样本的特征值从划分特征的位置上移除,并将剩余的特征值组成一

个新的样本,添加到划分后的子集中。如果样本的特征值小于等于阈值且方向不为0,同样进行相

同的操作。最后,返回划分后的子集。

4. 选择划分方式

#选择最好的数据集划分方式  
def chooseBestFeatureToSplit(dataSet,labels):  numFeatures=len(dataSet[0])-1  baseEntropy=calcShannonEnt(dataSet)  bestInfoGain=0.0  bestFeature=-1  bestSplitDict={}  for i in range(numFeatures):  featList=[example[i] for example in dataSet]  #  print(featList)#对连续型特征进行处理  if type(featList[0]).__name__=='float' or type(featList[0]).__name__=='int':  #产生n-1个候选划分点  sortfeatList=sorted(featList)  splitList=[]  for j in range(len(sortfeatList)-1):  splitList.append((sortfeatList[j]+sortfeatList[j+1])/2.0)  bestSplitEntropy=10000  slen=len(splitList)  #求用第j个候选划分点划分时,得到的信息熵,并记录最佳划分点  for j in range(slen):  value=splitList[j]  newEntropy=0.0  subDataSet0=splitContinuousDataSet(dataSet,i,value,0)  subDataSet1=splitContinuousDataSet(dataSet,i,value,1)  prob0=len(subDataSet0)/float(len(dataSet))  newEntropy+=prob0*calcShannonEnt(subDataSet0)  prob1=len(subDataSet1)/float(len(dataSet))  newEntropy+=prob1*calcShannonEnt(subDataSet1)  if newEntropy<bestSplitEntropy:  bestSplitEntropy=newEntropy  bestSplit=j  #用字典记录当前特征的最佳划分点  bestSplitDict[labels[i]]=splitList[bestSplit]  infoGain=baseEntropy-bestSplitEntropy  #对离散型特征进行处理  else:  uniqueVals=set(featList)  newEntropy=0.0  #计算该特征下每种划分的信息熵  for value in uniqueVals:  subDataSet=splitDataSet(dataSet,i,value)  prob=len(subDataSet)/float(len(dataSet))  print(prob)newEntropy+=prob*calcShannonEnt(subDataSet)  infoGain=baseEntropy-newEntropy  if infoGain>bestInfoGain:  bestInfoGain=infoGain  bestFeature=i  #若当前节点的最佳划分特征为连续特征,则将其以之前记录的划分点为界进行二值化处理  #即是否小于等于bestSplitValue  if type(dataSet[0][bestFeature]).__name__=='float' or type(dataSet[0][bestFeature]).__name__=='int':        bestSplitValue=bestSplitDict[labels[bestFeature]]          labels[bestFeature]=labels[bestFeature]+'<='+str(bestSplitValue)  for i in range(shape(dataSet)[0]):  if dataSet[i][bestFeature]<=bestSplitValue:  dataSet[i][bestFeature]=1  else:  dataSet[i][bestFeature]=0  return bestFeature  

numFeatures=len(dataSet[0])-1:计算数据集中特征数量,减去1是因为最后一列通常是标签列。

baseEntropy=calcShannonEnt(dataSet):计算整个数据集的基本熵。

bestInfoGain=0.0:初始化最佳信息增益为0。bestFeature=-1:初始化最佳划分特征的索引为-1。

bestSplitDict={}:创建一个空字典,用于记录连续特征的最佳划分点。

遍历每个特征,featList=[example[i] for example in dataSet]:获取数据集中第i个特征所有取值。

if type(featList[0]).__name__=='float' or ... :判断特征是否为连续型特征。

sortfeatList=sorted(featList):对连续型特征的取值进行排序。

splitList=[]:创建一个空列表,用于存储候选划分点。

for j in range(len(sortfeatList)-1):遍历排序后的特征取值列表,生成n-1个候选划分点。

splitList.append((sortfeatList[j]+sortfeatList[j+1])/2.0):将相邻特征值的平均值作为候选划分点。

bestSplitEntropy=10000:初始化最佳划分点的信息熵为一个较大的值。

slen=len(splitList):获取候选划分点的数量。for j in range(slen):遍历每个候选划分点。

value=splitList[j]:获取当前候选划分点的值。newEntropy=0.0:初始化划分后的信息熵为0。

         subDataSet0=splitContinuousDataSet(dataSet,i,value,0):根据当前候选划分点将数据集划

分为小于等于该值的子集。subDataSet1=splitContinuousDataSet(dataSet,i,value,1):根据当前候

选划分点将数据集划分为大于该值的子集。

        prob0=len(subDataSet0)/float(len(dataSet)):计算小于等于划分点的子集在整个数据集中的

概率。newEntropy+=prob0*calcShannonEnt(subDataSet0):计算小于等于划分点的子集的信息

熵,并加权求和。prob1=len(subDataSet1)/float(len(dataSet)):计算大于划分点的子集在整个数

据集中的概率。newEntropy+=prob1*calcShannonEnt(subDataSet1):计算大于划分点的子集的

信息熵,并加权求和。

if newEntropy<bestSplitEntropy:如果划分后的信息熵小于当前最佳划分点的信息熵。

bestSplitEntropy=newEntropy:更新最佳划分点的信息熵。

bestSplit=j:记录当前最佳划分点的索引。

bestSplitDict[labels[i]]=splitList[bestSplit]:用字典记录当前特征的最佳划分点。

infoGain=baseEntropy-bestSplitEntropy:计算当前特征的信息增益。

       如果特征是离散型特征,uniqueVals=set(featList):获取特征的唯一取值。newEntropy=0.0:

初始化划分后的信息熵为0。遍历每个离散特征取值。subDataSet=splitDataSet(dataSet,i,value):

根据当前特征取值将数据集划分为子集。prob=len(subDataSet)/float(len(dataSet)):计算当前特征

取值的概率。newEntropy+=prob*calcShannonEnt(subDataSet):计算当前特征取值的信息熵,并

加权求和。infoGain=baseEntropy-newEntropy:计算当前特征的信息增益if infoGain >

bestInfoGain:如果当前特征的信息增益大于当前最佳信息增益。bestInfoGain=infoGain:更新最

佳信息增益。bestFeature=i:记录当前最佳划分特征的索引。

       如果当前最佳划分特征是连续型特征。bestSplitValue=bestSplitDict[labels[bestFeature]]:获

取当前最佳划分特征的最佳划分点labels[bestFeature] = labels[bestFeature] + '<=' + str

(bestSplitValue):将当前最佳划分特征的标签更新为带有最佳划分点的条件。遍历数据集中的每个

样本。if dataSet[i][bestFeature]<=bestSplitValue:如果当前样本的最佳划分特征的取值小于等于

最佳划分点。dataSet[i][bestFeature]=1:将当前样本的最佳划分特征的取值设置为1。如果当前样

本的最佳划分特征的取值大于最佳划分点。dataSet[i][bestFeature]=0:将当前样本的最佳划分特

征的取值设置为0。返回最佳划分特征的索引。

5. 递归构造决策树

#特征若已经划分完,节点下的样本还没有统一取值,则需要进行投票  
def majorityCnt(classList):  classCount={}  for vote in classList:  if vote not in classCount.keys():  classCount[vote]=0  classCount[vote]+=1  return max(classCount)  #主程序,递归产生决策树  
def createTree(dataSet,labels,data_full,labels_full):  classList=[example[-1] for example in dataSet]  if classList.count(classList[0])==len(classList):  return classList[0]  if len(dataSet[0])==1:  return majorityCnt(classList)  bestFeat=chooseBestFeatureToSplit(dataSet,labels)  bestFeatLabel=labels[bestFeat]  myTree={bestFeatLabel:{}}  featValues=[example[bestFeat] for example in dataSet]  uniqueVals=set(featValues)  if type(dataSet[0][bestFeat]).__name__=='str':  currentlabel=labels_full.index(labels[bestFeat])  featValuesFull=[example[currentlabel] for example in data_full]  uniqueValsFull=set(featValuesFull)  del(labels[bestFeat])  #针对bestFeat的每个取值,划分出一个子树。  for value in uniqueVals:  subLabels=labels[:]  if type(dataSet[0][bestFeat]).__name__=='str':  uniqueValsFull.remove(value)  myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels,data_full,labels_full)  if type(dataSet[0][bestFeat]).__name__=='str':  for value in uniqueValsFull:  myTree[bestFeatLabel][value]=majorityCnt(classList)  return myTree 

classList=[example[-1] for example in dataSet]:创建一个列表classList,其中包含数据集dataSet

中每个样本的类别标签。

if classList.count(classList[0])==len(classList):检查classList中的类别标签是否都相同。如果是,

则返回该类别标签作为叶子节点的类别。

if len(dataSet[0])==1:检查数据集dataSet是否只剩下一个特征。如果是,则返回classList中出现

次数最多的类别标签作为叶子节点的类别。

bestFeat=chooseBestFeatureToSplit(dataSet,labels):调用函数chooseBestFeatureToSplit,选择

最佳的特征进行划分,并将其索引保存在bestFeat中。

bestFeatLabel=labels[bestFeat]:根据bestFeat的索引,获取特征标签labels中对应的特征名称。

myTree={bestFeatLabel:{}}:创建一个字典myTree,以bestFeatLabel作为键,空字典作为值。这

个字典将用于构建决策树。

featValues=[example[bestFeat] for example in dataSet]:创建一个列表featValues,其中包含数据

集dataSet中每个样本在bestFeat特征上的取值。

uniqueVals=set(featValues):将featValues转换为集合uniqueVals,以获取bestFeat特征的唯一取

值。

if type(dataSet[0][bestFeat]).__name__=='str':检查bestFeat特征的数据类型是否为字符串。

如果是,则执行以下操作:

      currentlabel=labels_full.index(labels[bestFeat]):获取完整特征标签列表labels_full中labels

[bestFeat]的索引,并将其保存在currentlabel中;          

      featValuesFull=[example[currentlabel] for example in data_full]:创建一个列表

featValuesFull,其中包含完整数据集data_full中每个样本在currentlabel特征上的取值;         

      uniqueValsFull=set(featValuesFull):将featValuesFull转换为集合uniqueValsFull,以获取

currentlabel特征的唯一取值。

del(labels[bestFeat]):删除labels中索引为bestFeat的特征标签,因为该特征已经被用于划分。

for value in uniqueVals:对于uniqueVals中的每个取值,执行以下操作:

       subLabels=labels[:]:创建一个新的特征标签列表subLabels,并将labels的值复制给它。

       if type(dataSet[0][bestFeat]).__name__=='str':如果bestFeat特征的数据类型为字符串,执行

以下操作:uniqueValsFull.remove(value):从uniqueValsFull中移除当前取值value。 

        myTree[bestFeatLabel[value] =createTree(splitDataSet(dataSet,bestFeat,value),subLabels,

data_ full,labels_full):递归调用createTree函数,传入划分后的子数据集、子特征标签列表以及完

整数据集和特征标签列表,并将返回的子树存储在myTree中。

        if type(dataSet[0][bestFeat]).__name__=='str':如果bestFeat特征的数据类型为字符串,执行

以下操作:for value in uniqueValsFull::对于uniqueValsFull中的每个取值,执行以下操作:

myTree[bestFeatLabel][value]=majorityCnt(classList):将叶子节点的类别标签设置为classList中

出现次数最多的类别标签。

最后,返回构建好的决策树。

df=pd.read_csv('watermelon_3a.csv')  
data=df.values[:,1:].tolist()  
data_full=data[:]  
labels=df.columns.values[1:-1].tolist()  
labels_full=labels[:]  
myTree=createTree(data,labels,data_full,labels_full) 

6. 画树 

import matplotlib.pyplot as plt
decisionNode=dict(boxstyle="sawtooth",fc="0.8")
leafNode=dict(boxstyle="round4",fc="0.8")
arrow_args=dict(arrowstyle="<-")#计算树的叶子节点数量
def getNumLeafs(myTree):numLeafs=0firstStr=list(myTree.keys())[0]secondDict=myTree[firstStr]for key in secondDict.keys():if type(secondDict[key]).__name__=='dict':numLeafs+=getNumLeafs(secondDict[key])else: numLeafs+=1return numLeafs#计算树的最大深度
def getTreeDepth(myTree):maxDepth=0firstStr=list(myTree.keys())[0]secondDict=myTree[firstStr]for key in secondDict.keys():if type(secondDict[key]).__name__=='dict':thisDepth=1+getTreeDepth(secondDict[key])else: thisDepth=1if thisDepth>maxDepth:maxDepth=thisDepthreturn maxDepth#画节点
def plotNode(nodeTxt,centerPt,parentPt,nodeType):createPlot.ax1.annotate(nodeTxt,xy=parentPt,xycoords='axes fraction',\xytext=centerPt,textcoords='axes fraction',va="center", ha="center",\bbox=nodeType,arrowprops=arrow_args)#画箭头上的文字
def plotMidText(cntrPt,parentPt,txtString):lens=len(txtString)xMid=(parentPt[0]+cntrPt[0])/2.0-lens*0.002yMid=(parentPt[1]+cntrPt[1])/2.0createPlot.ax1.text(xMid,yMid,txtString)def plotTree(myTree,parentPt,nodeTxt):numLeafs=getNumLeafs(myTree)depth=getTreeDepth(myTree)firstStr=list(myTree.keys())[0]cntrPt=(plotTree.x0ff+(1.0+float(numLeafs))/2.0/plotTree.totalW,plotTree.y0ff)plotMidText(cntrPt,parentPt,nodeTxt)plotNode(firstStr,cntrPt,parentPt,decisionNode)secondDict=myTree[firstStr]plotTree.y0ff=plotTree.y0ff-1.0/plotTree.totalDfor key in secondDict.keys():if type(secondDict[key]).__name__=='dict':plotTree(secondDict[key],cntrPt,str(key))else:plotTree.x0ff=plotTree.x0ff+1.0/plotTree.totalWplotNode(secondDict[key],(plotTree.x0ff,plotTree.y0ff),cntrPt,leafNode)plotMidText((plotTree.x0ff,plotTree.y0ff),cntrPt,str(key))plotTree.y0ff=plotTree.y0ff+1.0/plotTree.totalDdef createPlot(inTree):fig=plt.figure(1,facecolor='white')fig.clf()axprops=dict(xticks=[],yticks=[])createPlot.ax1=plt.subplot(111,frameon=False,**axprops)plotTree.totalW=float(getNumLeafs(inTree))plotTree.totalD=float(getTreeDepth(inTree))plotTree.x0ff=-0.5/plotTree.totalWplotTree.y0ff=1.0plotTree(inTree,(0.5,1.0),'')plt.show()

plotNode函数用于绘制节点。它接受节点文本(nodeTxt)、中心点(centerPt)、父节点(parentPt)和节

点类型(nodeType)作为参数。在函数内部,它使用createPlot.ax1.annotate()函数来绘制节点文

本。

createPlot函数用于创建并显示一个图形。它接受一个树对象(inTree)作为参数。在函数内部,它创

建了一个图形对象(fig),清除了图形对象中的内容,然后创建了一个子图对象(createPlot.ax1)。接

下来,它调用了plotTree函数来绘制树的节点,并使用plt.show()显示图形。

plotMidText函数用于在箭头上绘制文字。它接受三个参数:cntrPt表示箭头的中心点坐标,

parentPt表示箭头的起始点坐标,txtString表示要绘制的文字。在函数内部,它计算了文字的位置

坐标,并使用createPlot.ax1.text()函数在图形上绘制文字。

plotTree函数用于绘制树的节点和箭头。它接受三个参数:myTree表示树的字典表示,parentPt表

示父节点的坐标,nodeTxt表示节点的文本。在函数内部,它首先获取树的叶子节点数和深度,然

后计算当前节点的位置坐标。接下来,它调用plotMidText函数在箭头上绘制文字,调用plotNode函

数绘制节点。然后,它遍历树的子节点,如果子节点是字典类型,则递归调用plotTree函数绘制子

树;如果子节点是叶子节点,则调用plotNode函数绘制叶子节点,并使用plotMidText函数在箭头上

绘制文字。最后,它更新plotTree.y0ff的值,以便绘制下一层的节点。

遇到的问题:createPlot.ax1 是什么意思?

在这句代码中,createPlot是函数类型(function),而createPlot.ax1是一个

matplotlib.axes._axes.Axes。createPlot.ax1是一个有效的变量名,而将其替换为

createPlot_ax1会导致报错。在代码中,createPlot.ax1是一个全局变量,用于引用子图对象。

功能有点类似于类的成员变量,为了共享createPlot.ax1。函数也是对象,给一个对象绑定一个属

性就是这样的:函数对象本身就有很多属性,__name____doc__等等。自己绑定的要有意义,没

意义的就不需要。

def f():passf.a = 1
print(f.a) # 1
createPlot(myTree)

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初识Java 7-1 多态

目录 向上转型 难点 方法调用绑定 产生正确的行为 可扩展性 陷阱&#xff1a;“重写”private方法 陷阱&#xff1a;字段与静态方法 构造器和多态 构造器的调用顺序 继承和清理 构造器内部的多态方法行为 协变返回类型 使用继承的设计 替换和扩展 向下转型和反射…

Unity中Shader的变体shader_feature

文章目录 前言一、变体的类型1、multi_compile —— 无论如何都会被编译的变体2、shader_feature —— 通过材质的使用情况来决定是否编译的变体 二、使用 shader_feature 来控制 shader 效果的变化1、首先在属性面板暴露一个开关属性&#xff0c;用于配合shader_feature来控制…

Java(四)数组与类和对象

Java&#xff08;四&#xff09;数组与类和对象 六、数组&#xff08;非常重要&#xff09;1.定义2.遍历2.1遍历方法2.2Arrays方法 3.二维数组数组小总结 七、类和对象1. 定义&#xff08;重要&#xff09;1.1 类1.2 对象 2. this关键字&#xff08;重要&#xff09;2.1 特点 3…

lv4 嵌入式开发-4 标准IO的读写(二进制方式)

目录 1 标准I/O – 按对象读写 2 标准I/O – 小结 3 标准I/O – 思考和练习 文本文件和二进制的区别&#xff1a; 存储的格式不同&#xff1a;文本文件只能存储文本。除了文本都是二进制文件。 补充计算机内码概念&#xff1a;文本符号在计算机内部的编码&#xff08;计算…

肖sir__设计测试用例方法之正交表08_(黑盒测试)

设计测试用例方法之正交 一、正交表定义 正交试验设计法&#xff0c;是从大量的试验点中挑选出适量的、有代表性的点&#xff0c;应用依据迦罗瓦理论导出的“正交表”&#xff0c;合理的安排试验的一种科学的试验设计方法。 二、 正交常用的术语 指标&#xff1a;通常把判断试验…

OpenCV 12(图像直方图)

一、图像直方图 直方图可以让你了解总体的图像像素强度分布&#xff0c;其X轴为像素值&#xff08;一般范围为0~255&#xff09;&#xff0c;在Y轴上为图像中具有该像素值像素数。 - 横坐标: 图像中各个像素点的灰度级. - 纵坐标: 具有该灰度级的像素个数. 画出上图的直方图: …

【实践篇】Redis最强Java客户端(三)之Redisson 7种分布式锁使用指南

文章目录 0. 前言1. Redisson 7种分布式锁使用指南1.1 简单锁&#xff1a;1.2 公平锁&#xff1a;1.3 可重入锁&#xff1a;1.4 红锁&#xff1a;1.5 读写锁&#xff1a;1.6 信号量&#xff1a;1.7 闭锁&#xff1a; 2. Spring boot 集成Redisson 验证分布式锁3. 参考资料4. 源…

IntelliJ IDEA远程调试:使用IDEA Remote Debug进行高效调试的指南

引言 在开发分布式系统时&#xff0c;调试是一个重要但复杂的环节。开发者通常需要跨越多个服务、模块和线程来追踪和解决问题。在没有远程调试的情况下&#xff0c;许多开发者会在代码中添加各种日志语句&#xff0c;然后重新部署和上线来调试。这种方法不仅费时&#xff0c;…

Hive_Hive统计指令analyze table和 describe table

之前在公司内部经常会看到表的元信息的一些统计信息&#xff0c;当时非常好奇是如何做实现的。 现在发现这些信息主要是基于 analyze table 去做统计的&#xff0c;分享给大家 实现的效果某一个表中每个列的空值数量&#xff0c;重复值数量等&#xff0c;平均长度 具体的指令…

华为数据管理——《华为数据之道》

数据分析与开发 元数据是描述数据的数据&#xff0c;用于打破业务和IT之间的语言障碍&#xff0c;帮助业务更好地理解数据。 元数据是数据中台的重要的基础设施&#xff0c;元数据治理贯彻数据产生、加工、消费的全过程&#xff0c;沉淀了数据资产&#xff0c;搭建了技术和业务…

【C++模拟实现】手撕AVL树

【C模拟实现】手撕AVL树 目录 【C模拟实现】手撕AVL树AVL树的介绍&#xff08;百度百科&#xff09;AVL树insert函数的实现代码验证是否为AVL树AVL树模拟实现的要点易忘点AVL树的旋转思路 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2023.9.10 前言&#xff1a;本篇博客将…

python28种极坐标绘图函数总结

文章目录 基础图误差线等高线polar场图polar统计图非结构坐标图 &#x1f4ca;python35种绘图函数总结&#xff0c;3D、统计、流场&#xff0c;实用性拉满 matplotlib中的画图函数&#xff0c;大部分情况下只要声明坐标映射是polar&#xff0c;就都可以画出对应的极坐标图。但…

9、补充视频

改进后的dijkstra算法 利用小根堆 将小根堆特定位置更改,再改成小根堆 nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance);//改进后的dijkstra算法 //从head出发,所有head能到达的节点,生成到达每个节点的最小路径记录并返回 public static HashMap<No…

c语言练习44:深入理解strstr

深入理解strstr strstr作用展示&#xff1a; #include <stdio.h> #include <string.h> int main() {char str[] "This is a simple string";char* pch;pch strstr(str, "simple");/*strncpy(pch, "sample", 6);*/printf("%s…

Nginx详解 第五部分:Ngnix反向代理(负载均衡 动静分离 缓存 透传 )

Part 5 一、正向代理与反向代理1.1 正向代理简介1.2 反向代理简介 二、配置反向代理2.1 反向代理配置参数2.1.1 proxy_pass2.1.2 其余参数 2.2 配置实例:反向代理单台web服务器2.3 代理转发 三、反向代理实现动静分离四、缓存功能五、反向代理客户端的IP透传5.1 原理概述5.2 一…

基于语雀编辑器的在线文档编辑与查看

概述 语雀是一个非常优秀的文档和知识库工具&#xff0c;其编辑器更是非常好用&#xff0c;虽无开源版本&#xff0c;但有编译好的可以使用。本文基于语雀编辑器实现在线文档的编辑与文章的预览。 实现效果 实现 参考语雀编辑器官方文档&#xff0c;其实现需要引入以下文件&…

Pandas 掉包侠刷题实战--条件筛选

本博文内容为力扣刷题过程的记录&#xff0c;所有题目来源于力扣。 题目链接&#xff1a;https://leetcode.cn/studyplan/30-days-of-pandas/ 文章目录 准备工作1. isin(values) 和 ~2. df.drop_duplicates()3. df.sort_values()4. df.rename()5. pd.merge() 题目-条件筛选1. 大…

入门人工智能 —— 使用 Python 进行文件读写,并完成日志记录功能(4)

入门人工智能 —— 使用 Python 进行文件读写&#xff08;4&#xff09; 入门人工智能 —— 使用 Python 进行文件读写打开文件读取文件内容读取整个文件逐行读取文件内容读取所有行并存储为列表 写入文件内容关闭文件 日志记录功能核心代码&#xff1a;完整代码&#xff1a;运…

RabbitMQ从入门到精通之安装、通讯方式详解

文章目录 RabbitMQ一、RabbitMQ介绍1.1 现存问题 一、RabbitMQ介绍二、RabbitMQ安装三、RabbitMQ架构四、RabbitMQ通信方式4.1 RabbitMQ提供的通讯方式4.2 Helloworld 方式4.2Work queues4.3 Publish/Subscribe4.4 Routing4.5 Topics4.6 RPC (了解) 五、Springboot 操作RabbitM…

【结合AOP与ReflectUtil对返回数据进行个性化填充展示】

结合AOP与ReflectUtil对返回数据进行个性化填充展示 背景 对于接口列表返回的数据&#xff0c;我们通常有时候会对某些特殊的字段进行转化&#xff0c;或者根据某逻辑进行重新赋值&#xff0c;举个例子&#xff0c; 比如返回的列表数据中有性别sex&#xff0c;我们通常会同时…