-
1. 首先登陆谷歌云盘,上传自己的项目 左上角+号,可以上传整个文件夹、单个文件,选择自己的项目代码,上传到自定义目录 2. 新建Colab 还是左上角的new,找到Google Colaboratory,会新建一个Colab笔记,如下,可自行修改名字 目前就和jupyter notebook差不多的使用方法,可以新建代码段,并运行 3. 配置GPU 按如下,修改->笔记本设置(我的是中文的) 选择GPU ,保存,等待分配GPU 4. 挂载谷歌云盘 输入命令 from google.colab import drive drive.mount('/content/drive/') 会提示登录谷歌账号,登录即可 5. 切换到自己的项目目录下 import os os.chdir('/content/drive/My Drive/项目目录/') 6. 运行python文件 .py后可根据需要加参数 %run demo.py ———————————————— 版权声明:本文为CSDN博主「biu piu biu piu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/MISS_XDY/article/details/127729000
-
环境准备 Python3.5以上 Appium Server服务器 Android SDK,需要用到adb服务 需要依赖Appium-Python-Client组件库 真机或者模拟器,推荐模拟器(真机一般安卓8版本以上了,appium对安卓8以上版本元素获取的兼容性不太好) JDK8环境 实现 确保adb服务和appium服务及真机/模拟器正常打开,然后在真机/模拟器上将抖音打开。 确定需要的参数 参数基本上都是固定的,只需要确定抖音的包名和活动页即可。 adb shell dumpsys window | findstr mCurrentFocus获取到抖音的包名数据,最后代码里的参数: desired_caps = { "platformName": "Android", # 平台是安卓的 "deviceName": "127.0.0.1:62001", # 通过 adb devices命令获取 "appPackage": "com.ss.android.ugc.aweme", # 抖音包名 "appActivity": ".splash.SplashActivity", # 活动页 "platformVersion":"7.1" # 7.1.2 } 参数整完记得项目跑起来测试一下。 控制模拟器进入抖音后 我们需要去获取页面上的元素或坐标,来实现滑动视频等其他操作。 到我们的Android SDK的tools目录下使用uiautomatoviewer.bat取页面快照。 操作的过程其实相对简单,就是实现页面滑动即可;可能会遇到弹框、点击授权之类的,处理一下即可。然后还需要注意的就是元素的加载时间问题,尽量考虑好网络、设备等其他因素,将等待时间放长些。 # @creator by wlh # @date 2023/3/15 19:43 import time from appium import webdriver from appium.webdriver.common.touch_action import TouchAction from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as ec desired_caps = { "platformName": "Android", "deviceName": "127.0.0.1:62001", # 通过 adb devices命令获取 "appPackage": "com.ss.android.ugc.aweme", "appActivity": ".splash.SplashActivity", "platformVersion": "7.1" # 7.1.2 } driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps) driver.implicitly_wait(20) # 等待弹框元素 driver.find_element(By.XPATH, "//*[@text='同意']").click() driver.implicitly_wait(20) # 等待弹框元素 driver.find_element(By.XPATH, "//*[@text='允许']").click() time.sleep(1.5) size = driver.get_window_size() width, height = size['width'], size['height'] # 获取屏幕宽高 action = TouchAction(driver) for i in range(5): # 实现滑动 action.press(x=width / 2, y=height / 3 * 2).wait(500).move_to(x=width / 2, y=height / 3).release() action.perform() try: # 3s后 弹框元素不出现,直接跳过继续执行 WebDriverWait(driver, 3).until(ec.presence_of_element_located((By.XPATH, "//*[@text='允许']"))) driver.find_element(By.XPATH, "//*[@text='允许']").click() except: pass time.sleep(5) driver.close_app() driver.quit() ———————————————— 版权声明:本文为CSDN博主「鸢尾の」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_45248492/article/details/129584410
-
环境使用: Python 3.8 Pycharm mou歌浏览器 mou歌驱动 —> 驱动版本要和浏览器版本最相近 <大版本一样, 小版本最相近> 模块使用: requests >>> pip install requests selenium >>> pip install selenium==3.141.0 <需要浏览器和浏览器驱动> 默认安装 4.0版本 语法上面有点区别 re json 卸载模块: pip uninstall selenium 卸载模块 安装python第三方模块: win + R 输入 cmd 点击确定, 输入安装命令 pip install 模块名 (pip install requests) 回车 在pycharm中点击Terminal(终端) 输入安装命令 基本思路流程: <通用> 一. 数据来源分析: 明确需求: 采集什么数据内容 I. 视频播放链接 II. 视频标题 通过浏览器自带工具: 开发者工具, 进行抓包分析 打开开发者工具: F12 / 鼠标右键点击检查选择network 刷新网页: 让本网页数据内容重新加载一遍 分析/找到 视频播放链接在哪里 选择 media <媒体文件> 可以直接看到 视频播放链接 通过搜索分析可以直接找到 视频播放链接/ 视频标题 二. 代码实现步骤: 发送请求, 模拟浏览器对于url地址发送请求 获取数据, 获取服务器返回响应数据 开发者工具: response <网页源代码> 解析数据, 提取我们想要的数据内容 视频标题 视频播放链接 保存数据, 把视频内容保存本地文件夹 代码展示 导入模块 导入数据请求模块 import requests import re import json from pprint import pprint from selenium import webdriver import time 创建浏览器对象, 实例化对象 自动打开浏览器 driver = webdriver.Chrome() 1 访问网址【需要网址的私我吧这不给放】 执行页面滚动的操作 def drop_down(): for x in range(1, 40, 4): time.sleep(1) j = x / 9 js = 'document.documentElement.scrollTop = document.documentElement.scrollHeight * %f' % j driver.execute_script(js) 可以直接定位元素提取内容 lis = driver.find_elements_by_css_selector('.Eie04v01') for li in lis: url = li.find_element_by_css_selector('a').get_attribute('href') 1 2 3 1. 发送请求, 模拟浏览器对于url地址发送请求 <Response [200]> 响应对象, 表示请求成功 仅表示请求成功, 但是不代表一定得到数据<你想要的数据> 没有得到我们想要的数据内容: 原因: 是因为代码被服务器识别出来了, 是pachong程序 解决:把代码伪装成浏览器去发送请求 —> headers 请求头 print(url) time.sleep(1) 确定请求链接 <视频播放页面> 模拟伪装 headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36' } 发送请求 response = requests.get(url=url, headers=headers) 获取数据, 获取服务器返回响应数据 开发者工具: response <网页源代码> 解析数据, 提取我们想要的数据内容 视频标题 视频播放链接 正则表达式, 你要获取什么数据, 直接复制过来, 然后要的数据内容用 (.*?) 表示, 会直接给返回相应的内容 .*? 表示可以匹配任意字符串, 除了\n换行符以外 提取标题 title = re.findall('<title data-react-helmet="true">(.*?)</title>', response.text, re.S)[0] 1 替换一下特殊字符 title = re.sub(r'[\/:*?"<>|\n]', '', title) 1 提取视频信息 video_info = re.findall('<script id="RENDER_DATA" type="application/json">(.*?)</script', response.text)[0] 数据进行解码 html_data = requests.utils.unquote(video_info) 转换数据类型 json_data = json.loads(html_data) 键值对取值, 根据冒号左边的内容[键], 提取冒号右边的内容[值] video_url = 'https:' + json_data['41']['aweme']['detail']['video']['bitRateList'][0]['playAddr'][0]['src'] print(title) print(video_url) 4. 保存数据 video_content = requests.get(url=video_url, headers=headers).content with open('video\\' + title + '.mp4', mode='wb') as f: f.write(video_content) 1 2 3 我是爱学python的蚂蚁,咱下篇文章再见啦(✿◡‿◡) 有更多建议或问题可以评论区或私信我哦!一起加油努力叭(ง •_•)ง 喜欢就关注一下博主,或点赞收藏评论一下我的文章叭!!! ———————————————— 版权声明:本文为CSDN博主「蚂蚁爱Python」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/xff123456_/article/details/129287579
-
Jetson NX 配置pytorch备注:参考博客最后安装的pytorch无法使用cuda-----目前没找到原因,不知如何解决。但是官方的教程没问题!环境情况: 系统JetPack 5.0.2 --ubuntu20.04 配置流程 安装miniconda(流程省略)conda create -n pytorch python=3.8 安装pytorchsudo apt-get -y update;sudo apt-get -y install autoconf bc build-essential g++-8 gcc-8 clang-8 lld-8 gettext-base gfortran-8 iputils-ping libbz2-dev libc++-dev libcgal-dev libffi-dev libfreetype6-dev libhdf5-dev libjpeg-dev liblzma-dev libncurses5-dev libncursesw5-dev libpng-dev libreadline-dev libssl-dev libsqlite3-dev libxml2-dev libxslt-dev locales moreutils openssl python-openssl rsync scons python3-pip libopenblas-dev;sudo apt-get install python3-pip libopenblas-base libopenmpi-devconda activate pytorchpip3 install Cython添加环境变量export PATH=/usr/local/cuda/bin:$PATHexport LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATHexport CUDA_ROOT=/usr/local/cudaexport TORCH_INSTALL=https://developer.download.nvidia.cn/compute/redist/jp/v51/pytorch/torch-1.14.0a0+44dac51c.nv23.02-cp38-cp38-linux_aarch64.whlpython3 -m pip install --upgrade pip; python3 -m pip install aiohttp numpy=='1.19.4' scipy=='1.5.3'; python3 -m pip install --upgrade protobuf; python3 -m pip install --no-cache $TORCH_INSTALLtorchvision pip install torchvision测试结果>>> import torch >>> print(torch.__version__) >>> print('CUDA available: ' + str(torch.cuda.is_available())) >>> print('cuDNN version: ' + str(torch.backends.cudnn.version())) >>> a = torch.cuda.FloatTensor(2).zero_() >>> print('Tensor a = ' + str(a)) >>> b = torch.randn(2).cuda() >>> print('Tensor b = ' + str(b)) >>> c = a + b >>> print('Tensor c = ' + str(c)) >>> import torchvision >>> print(torchvision.__version__)配合repvgg的部署 pip install opencv-contrib-pythonpip install matplotlibpip install torchvision 其他问题报错:ImportError: cannot import name ‘PILLOW_VERSION’ from ‘PIL’ (/home/jiajie/anaconda3/envs/py35/lib/python3.7/site-packages/PIL/init.py)解决:pip index versions pillow or conda search pillowpip3 install pillow==6.2.0警告:UserWarning: Failed to load image Python extension:warn(f"Failed to load image Python extension: {e}")解决:没解决,据说是pytorch版本太高,或者是pytorch与torchvision版本不契合pytorch版本与jetpack的选择安装pytorch 中第7步,不同版本的jetpack需要根据情况修改版本,
-
Swin Transformer是一种用于图像处理的深度学习模型,它可以用于各种计算机视觉任务,如图像分类、目标检测和语义分割等。它的主要特点是采用了分层的窗口机制,可以处理比较大的图像,同时也减少了模型参数的数量,提高了计算效率。Swin Transformer在图像处理领域取得了很好的表现,成为了最先进的模型之一。Swin Transformer通过从小尺寸的图像块(用灰色轮廓线框出)开始,并逐渐合并相邻块,构建了一个分层的表示形式,在更深层的Transformer中实现。Swin Transformer 模块Swin Transformer模块是基于Transformer块中标准的多头自注意力模块(MSA)进行替换构建的,用的是一种基于滑动窗口的模块(在后面细说),而其他层保持不变。如上图所示,Swin Transformer模块由基于滑动窗口的多头注意力模块组成,后跟一个2层MLP,在中间使用GELU非线性激活函数。在每个MSA模块和每个MLP之前都应用了LayerNorm(LN)层,并在每个模块之后应用了残差连接。滑动窗口机制Cyclic ShiftCyclic Shift是Swin Transformer中一种有效的处理局部特征的方法。在Swin Transformer中,为了处理高分辨率的输入特征图,需要将输入特征图分割成小块(一个patch可能有多个像素)进行处理。然而,这样会导致局部特征在不同块之间被分割开来,影响了局部特征的提取。Cyclic Shift将输入特征图沿着宽度和高度方向分别平移一个固定的距离,使得每个块的局部特征可以与相邻块的局部特征进行交互,从而增强了局部特征的表达能力。另外,Cyclic Shift还可以通过多次平移来增加块之间的交互,进一步提升了模型的性能。需要注意的是,Cyclic Shift只在训练过程中使用,因为它会改变输入特征图的分布。在测试过程中,输入特征图的大小和分布与训练时相同,因此不需要使用Cyclic Shift操作。Efficient batch computation for shifted configurationCyclic Shift会将输入特征图沿着宽度和高度方向进行平移操作,以便让不同块之间的局部特征进行交互。这样的操作会导致每个块的特征值的位置发生改变,从而需要在每个块上重新计算注意力机制。为了加速计算过程,Swin Transformer中引入了"Efficient batch computation for shifted configuration"这一技巧。该技巧首先将每个块的特征值复制多次,分别放置在Cyclic Shift平移后的不同位置上,使得每个块都可以在平移后的不同的位置上参与到注意力机制的计算中。然后,将这些位置不同的块的特征值进行合并拼接,计算注意力。需要注意的是,这种技巧只在训练时使用,因为它会增加计算量,而在测试时,可以将每个块的特征值计算一次,然后在不同位置上进行拼接,以得到最终的输出。Relative position bias在传统的Transformer模型中,为了考虑单词之间的位置关系,通常采用绝对位置编码(Absolute Positional Encoding)的方式。这种方法是在每个单词的embedding中添加位置编码向量,以表示该单词在序列中的绝对位置。但是,当序列长度很长时,绝对位置编码会面临两个问题:编码向量的大小会随着序列长度的增加而增加,导致模型参数量增大,训练难度加大;当序列长度超过一定限制时,模型的性能会下降。为了解决这些问题,Swin Transformer采用了Relative Positional Encoding,它通过编码单词之间的相对位置信息来代替绝对位置编码。相对位置编码是由每个单词对其它单词的相对位置关系计算得出的。在计算相对位置时,Swin Transformer引入了Relative Position Bias,即相对位置偏置,它是一个可学习的参数矩阵,用于调整不同位置之间的相对位置关系。这样做可以有效地减少相对位置编码的参数量,同时提高模型的性能和效率。相对位置编码可以通过以下公式计算:最终,相对位置编码和相对位置偏置的结果会被加到点积注意力机制中,用于计算不同位置之间的相关性,从而实现序列的建模。代码实现:下面是一个用PyTorch实现Swin B模型的示例代码,其中包含了相对位置编码和相对位置偏置的实现:
-
使用背景逛社区发现许多人在解决删除文件夹中非图片文件,删除文件夹中图片等问题的时候,都写了很多代码取实现这一功能,我当时就纳闷了,能几行代码解决的事,为什么要写那么多的代码?解决下述问题解决的问题是:删除文件夹中具有相同后缀类型文件。如删除文件夹下所有的JPG文件或者PNG文件核心函数str.endswith(suffix[, start[, end]])函数用法: endswith() 方法用于判断字符串是否以指定后缀结尾,如果以指定后缀结尾返回True,否则返回False。可选参数"start"与"end"为检索字符串的开始与结束位置。suffix – 该参数可以是一个字符串或者是一个元素。start – 字符串中的开始位置。end – 字符中结束位置。注:返回值为bool类型实战演练现在文件夹中有TXT文件(后缀为.txt),CSV文件(后缀为.csv)和PNG文件(后缀为.png),需要删除PNG文件,只保留TXT和CSV文件。代码如下所示:import os file=os.listdir(r'C:\Users\ZFG\Desktop\test') for i in file: if i.endswith('.png'): os.remove(r'C:\Users\ZFG\Desktop\test/'+i)#i保存的只是文件夹中的一个相对路径,绝对路径还需要加上文件夹的路径+‘/' 附:以下代码是删除指定目录下的jpg图片 # 删除文件夹下面的图片 #先导入所需的包 import os #指定路径 path = '/content/drive/My Drive' filenames = os.listdir(path) for filename in filenames: print(filename) #判断是否是文件而非文件夹 if(os.path.isfile(filename)): # print('it is a file') #判断文件后缀名是否是‘.jpg' if(os.path.splitext(filename)[1] == '.jpg'): #执行删除 os.remove(filename)
-
导入必要的库和模块以下是使用TensorFlow创建一个生成式对抗网络(GAN)的案例: 首先,我们需要导入必要的库和模块:import tensorflow as tf from tensorflow.keras import layers import matplotlib.pyplot as plt import numpy as np 然后,我们定义生成器和鉴别器模型。生成器模型将随机噪声作为输入,并输出伪造的图像。鉴别器模型则将图像作为输入,并输出一个0到1之间的概率值,表示输入图像是真实图像的概率。# 定义生成器模型 def make_generator_model(): model = tf.keras.Sequential() model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,))) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Reshape((7, 7, 256))) assert model.output_shape == (None, 7, 7, 256) model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False)) assert model.output_shape == (None, 7, 7, 128) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False)) assert model.output_shape == (None, 14, 14, 64) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh')) assert model.output_shape == (None, 28, 28, 1) return model # 定义鉴别器模型 def make_discriminator_model(): model = tf.keras.Sequential() model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1])) model.add(layers.LeakyReLU()) model.add(layers.Dropout(0.3)) model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same')) model.add(layers.LeakyReLU()) model.add(layers.Dropout(0.3)) model.add(layers.Flatten()) model.add(layers.Dense(1)) return model 定义训练循环在每个epoch中,我们将随机生成一组噪声作为输入,并使用生成器生成伪造图像。然后,我们将真实图像和伪造图像一起传递给鉴别器,计算鉴别器和生成器的损失函数,并使用优化器更新模型参数。# 定义训练循环 @tf.function def train_step(images): noise = tf.random.normal([BATCH_SIZE, 100]) with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape: generated_images = generator(noise, training=True) real_output = discriminator(images, training=True) fake_output = discriminator(generated_images, training=True) gen_loss = generator_loss(fake_output) disc_loss = discriminator_loss(real_output, fake_output) gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables) gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables) generator_optimizer.appy_gradients(zip(gradients_of_generator, generator.trainable_variables)) discriminator_optimizer.appy_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables)) 最后定义主函数加载MNIST数据集并训练模型。# 加载数据集 (train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data() train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32') train_images = (train_images - 127.5) / 127.5 # 将像素值归一化到[-1, 1]之间 BUFFER_SIZE = 60000 BATCH_SIZE = 256 train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE) # 创建生成器和鉴别器模型 generator = make_generator_model() discriminator = make_discriminator_model() # 训练模型 EPOCHS = 100 noise_dim = 100 num_examples_to_generate = 16 # 用于可视化生成的图像 seed = tf.random.normal([num_examples_to_generate, noise_dim]) for epoch in range(EPOCHS): for image_batch in train_dataset: train_step(image_batch) # 每个epoch结束后生成一些图像并可视化 generated_images = generator(seed, training=False) fig = plt.figure(figsize=(4, 4)) for i in range(generated_images.shape[0]): plt.subplot(4, 4, i+1) plt.imshow(generated_images[i, :, :, 0] * 127.5 + 127.5, cmap='gray') plt.axis('off') plt.show()
-
使用Python对文件进行批量改名Python在Windows系统下的路径表示回顾:反斜杠“\”是转义符,如果继续用windows习惯使用“\”表示文件路径,就会产生歧义。Windows下的原始路径:C:\Users\LUO\Documents\GitHub\CalculatorT3000\introduction所以在Python中有三种方法表示:path="C:\\Users\\LUO\\Documents\\GitHub\\CalculatorT3000\\introduction\\" path=r'C:\Users\LUO\Documents\GitHub\CalculatorT3000\introduction\'path='C:/Users/LUO/Documents/GitHub/CalculatorT3000/introduction/'使用斜杠“/”: 'C:/Users/LUO/Documents/GitHub/CalculatorT3000/introduction/' 将反斜杠符号转义: "C:\\Users\\LUO\\Documents\\GitHub\\CalculatorT3000\\introduction\\" 因为反斜杠是转义符,所以两个"\\"就表示一个反斜杠符号 使用Python的raw string:r'C:\Users\LUO\Documents\GitHub\CalculatorT3000\introduction\' python下在字符串前面加上字母r,表示后面是一个原始字符串raw string,不过raw string主要是为正则表达式而不是windows路径设计的,所以这种做法尽量少用,可能会出问题使用os 模块来处理文件和目录python 对文件进行批量改名用到的是 os 模块中的 listdir 方法和 rename 方法。os.listdir(dir) : 获取指定目录下的所有子目录和文件名os.rename(原文件名,新文件名) :os.rename(src, dst) 方法用于命名文件或目录,从 src 到 dst,如果dst是一个存在的目录, 将抛出OSErroros.renames() 方法用于递归重命名目录或文件。类似rename()os.renames(old, new)old -- 要重命名的目录new --文件或目录的新名字。甚至可以是包含在目录中的文件,或者完整的目录树os.getcwd() 返回当前工作目录os.path 模块主要用于获取文件的属性os.path.basename(path)返回文件名os.path.dirname(path)返回文件路径os.path.exists(path)如果路径 path 存在,返回 True;如果路径 path 不存在,返回 False。os.path.getmtime(path)返回最近文件修改时间os.path.getctime(path)返回文件 path 创建时间os.path.getsize(path)返回文件大小,如果文件不存在就返回错误os.path.isfile(path)判断路径是否为文件os.path.isdir(path)判断路径是否为目录os.path.samefile(path1, path2)判断目录或文件是否相同os.path.sameopenfile(fp1, fp2)判断fp1和fp2是否指向同一文件import os #三种路径表示方法 #path="C:\\Users\\LUO\\Documents\\GitHub\\CalculatorT3000\\introduction\\" #转义符的方式不能在此使用 #path=r'C:\Users\LUO\Documents\GitHub\CalculatorT3000\introduction\' #path='C:/Users/LUO/Documents/GitHub/CalculatorT3000/introduction/' #从控制台输入 path=input("请输入需要改名的路径:") #判断路径是否存在 if os.path.exists(path): #获取该目录下所有文件,存入列表中 fileList=os.listdir(path) n=0 for i in fileList: #设置旧文件名(就是路径+文件名) oldname=path+ os.sep + fileList[n] # os.sep添加系统分隔符 #判断当前是否是文件 if os.path.isfile(oldname): #设置新文件名 newname=path + os.sep +'calc_'+str(n+1)+'.jpg' os.rename(oldname,newname) #用os模块中的rename方法对文件改名 print(oldname,'======>',newname) n+=1 else: print('路径不存在') 补充:使用python批量修改文件名使用python对文件名进行批量修改使用split方法对原文件名进行切分,选择需要的部分进行保留做为新的文件名,也可添加字段。函数说明split()函数语法:str.split(str="",num=string.count(str))[n]参数说明:str: 表示为分隔符,默认为空格,但是不能为空(’’)。若字符串中没有分隔符,则把整个字符串作为列表的一个元素num:表示分割次数。如果存在参数num,则仅分隔成 num+1 个子字符串,并且每一个子字符串可以赋给新的变量[n]: 表示选取第n个分片注意:当使用空格作为分隔符时,对于中间为空的项会自动忽略 import os import re def changename(orignname): picture=os.listdir(orignname) for filename in picture: # filename1 = filename.split(".")[0] # filename2=re.findall(r"\d+\.?\d*", filename1)[0]+".png" # srcpath = os.path.join(orignname,filename) # allpath = os.path.join(orignname,filename2) # os.rename(srcpath,allpath) #split("_",2)[1] “_”表示分隔符 ; 2表示分割次数 ; [1]表示选取第 i 个片段 filename1=filename.split("_")[3] #设置旧文件名(就是路径+文件名) srcpath=os.path.join(orignname,filename) #设置新文件名 allpath= os.path.join(orignname,filename1) os.rename(srcpath, allpath) if __name__ == '__main__': orignname=r"D:\AK\GJ\dataset_2\val\labels" changename(orignname)注意:该方法是直接覆盖原图的文件名,不另存,如果想要保留原文件名,请提前复制
-
一、os.system方法这个方法是直接调用标准C的system() 函数,仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息。os.system(cmd)的返回值。如果执行成功,那么会返回0,表示命令执行成功。否则,则是执行错误。使用os.system返回值是脚本的退出状态码,该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码,高位为脚本的退出状态码。os.system()返回值为0 linux命令返回值也为0。os.system()返回值为256,十六位二进制数示为:00000001,00000000,高八位转成十进制为 1 对应 linux命令返回值 1。os.system()返回值为512,十六位二进制数示为:00000010,00000000,高八位转成十进制为 2 对应 linux命令返回值 2。import os result = os.system('cat /etc/passwd') print(result) # 0二、os.popen方法os.popen()方法不仅执行命令而且返回执行后的信息对象(常用于需要获取执行命令后的返回信息),是通过一个管道文件将结果返回。通过 os.popen() 返回的是 file read 的对象,对其进行读取 read() 的操作可以看到执行的输出。import os result = os.popen('cat /etc/passwd') print(result.read())三、commands模块import commands status = commands.getstatus('cat /etc/passwd') print(status) output = commands.getoutput('cat /etc/passwd') print(output) (status, output) = commands.getstatusoutput('cat /etc/passwd') print(status, output)四、subprocess模块Subprocess是一个功能强大的子进程管理模块,是替换os.system,os.spawn* 等方法的一个模块。当执行命令的参数或者返回中包含了中文文字,那么建议使用subprocess。import subprocess res = subprocess.Popen('cat /etc/passwd', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # 使用管道 print res.stdout.read() # 标准输出 for line in res.stdout.readlines(): print line res.stdout.close() # 关闭五、总结:os.system:获取程序执行命令的返回值。os.popen: 获取程序执行命令的输出结果。commands:获取返回值和命令的输出结果。
-
Vision Transformer(VIT)Vision Transformer(ViT)是一种新兴的图像分类模型,它使用了类似于自然语言处理中的Transformer的结构来处理图像。这种方法通过将输入图像分解成一组图像块,并将这些块变换为一组向量来处理图像。然后,这些向量被输入到Transformer编码器中,以便对它们进行进一步的处理。ViT在许多计算机视觉任务中取得了与传统卷积神经网络相当的性能,但其在处理大尺寸图像和长序列数据方面具有优势。与自然语言处理(NLP)中的Transformer模型类似,ViT模型也可以通过预训练来学习图像的通用特征表示。在预训练过程中,ViT模型通常使用自监督任务,如图像补全、颜色化、旋转预测等,以无需人工标注的方式对图像进行训练。这些任务可以帮助ViT模型学习到更具有判别性和泛化能力的特征表示,并为下游的计算机视觉任务提供更好的初始化权重。Patch EmbeddingsPatch embedding是Vision Transformer(ViT)模型中的一个重要组成部分,它将输入图像的块转换为向量,以便输入到Transformer编码器中进行处理。Patch embedding的过程通常由以下几个步骤组成:图像切片:输入图像首先被切成大小相同的小块,通常是16x16、32x32或64x64像素大小。这些块可以重叠或不重叠,取决于具体的实现方式。展平像素:每个小块内的像素被展平成一个向量,以便能够用于后续的矩阵计算。展平的像素向量的长度通常是固定的,与ViT的超参数有关。投影:接下来,每个像素向量通过一个可学习的线性变换(通常是一个全连接层)进行投影,以便将其嵌入到一个低维的向量空间中。拼接:最后,所有投影向量被沿着一个维度拼接在一起,形成一个大的二维张量。这个张量可以被看作是输入序列的一个矩阵表示,其中每一行表示一个图像块的嵌入向量。通过这些步骤,Patch embedding将输入的图像块转换为一组嵌入向量,这些向量可以被输入到Transformer编码器中进行进一步的处理。Patch embedding的设计使得ViT能够将输入图像的局部特征信息编码成全局特征,从而实现了对图像的整体理解和分类。Inductive bias在Vision Transformer(ViT)模型中,也存在着Inductive bias,它指的是ViT模型的设计中所假定的先验知识和偏见,这些知识和偏见可以帮助模型更好地学习和理解输入图像。ViT的Inductive bias主要包括以下几个方面:图像切片:ViT将输入图像划分为多个大小相同的块,每个块都是一个向量。这种切片方式的假设是,输入图像中的相邻区域之间存在着相关性,块内像素的信息可以被整合到一个向量中。线性投影:在Patch embedding阶段,ViT将每个块的像素向量通过线性投影映射到一个较低维度的向量空间中。这种映射方式的假设是,输入图像的特征可以被表示为低维空间中的点,这些点之间的距离可以捕捉到图像的局部和全局结构。Transformer编码器:ViT的编码器部分采用了Transformer结构,这种结构能够对序列中的不同位置之间的依赖关系进行建模。这种建模方式的假设是,输入图像块之间存在着依赖关系,这些依赖关系可以被利用来提高模型的性能。通过这些Inductive bias,ViT模型能够对输入图像进行有效的表示和学习。这些假设和先验知识虽然有一定的局限性,但它们可以帮助ViT更好地处理图像数据,并在各种计算机视觉任务中表现出色。Hybrid Architecture在ViT中,Hybrid Architecture是指将卷积神经网络(CNN)和Transformer结合起来,用于处理图像数据。Hybrid Architecture使用一个小的CNN作为特征提取器,将图像数据转换为一组特征向量,然后将这些特征向量输入Transformer中进行处理。CNN通常用于处理图像数据,因为它们可以很好地捕捉图像中的局部和平移不变性特征。但是,CNN对于图像中的全局特征处理却有一定的局限性。而Transformer可以很好地处理序列数据,包括文本数据中的全局依赖关系。因此,将CNN和Transformer结合起来可以克服各自的局限性,同时获得更好的图像特征表示和处理能力。在Hybrid Architecture中,CNN通常被用来提取局部特征,例如边缘、纹理等,而Transformer则用来处理全局特征,例如物体的位置、大小等。具体来说,Hybrid Architecture中的CNN通常只包括几层卷积层,以提取一组局部特征向量。然后,这些特征向量被传递到Transformer中,以捕捉它们之间的全局依赖关系,并输出最终的分类或回归结果。相对于仅使用Transformer或CNN来处理图像数据,Hybrid Architecture在一些图像任务中可以取得更好的结果,例如图像分类、物体检测等。Fine-tuning and higher resolution在ViT模型中,我们通常使用一个较小的分辨率的输入图像(例如224x224),并在预训练阶段将其分成多个固定大小的图像块进行处理。然而,当我们将ViT模型应用于实际任务时,我们通常需要处理更高分辨率的图像,例如512x512或1024x1024。为了适应更高分辨率的图像,我们可以使用两种方法之一或两种方法的组合来提高ViT模型的性能:Fine-tuning: 我们可以使用预训练的ViT模型来初始化网络权重,然后在目标任务的数据集上进行微调。这将使模型能够在目标任务中进行特定的调整和优化,并提高其性能。Higher resolution: 我们可以增加输入图像的分辨率来提高模型的性能。通过处理更高分辨率的图像,模型可以更好地捕捉细节信息和更全面的视觉上下文信息,从而提高模型的准确性和泛化能力。通过Fine-tuning和Higher resolution这两种方法的组合,我们可以有效地提高ViT模型在计算机视觉任务中的表现。这种方法已经在许多任务中取得了良好的结果,如图像分类、目标检测和语义分割等。PyTorch实现Vision Transformerimport torch import torch.nn as nn import torch.nn.functional as F from torchvision import transforms, datasets # 定义ViT模型 class ViT(nn.Module): def __init__(self, image_size=224, patch_size=16, num_classes=1000, dim=768, depth=12, heads=12, mlp_dim=3072): super(ViT, self).__init__() # 输入图像分块 self.image_size = image_size self.patch_size = patch_size self.num_patches = (image_size // patch_size) ** 2 self.patch_dim = 3 * patch_size ** 2 self.proj = nn.Conv2d(3, dim, kernel_size=patch_size, stride=patch_size) # Transformer Encoder self.transformer_encoder = nn.TransformerEncoder(nn.TransformerEncoderLayer(d_model=dim, nhead=heads, dim_feedforward=mlp_dim), num_layers=depth) # MLP head self.layer_norm = nn.LayerNorm(dim) self.fc = nn.Linear(dim, num_classes) def forward(self, x): # 输入图像分块 x = self.proj(x) x = x.flatten(2).transpose(1, 2) # Transformer Encoder x = self.transformer_encoder(x) # MLP head x = self.layer_norm(x.mean(1)) x = self.fc(x) return x # 加载CIFAR-10数据集 transform = transforms.Compose([transforms.Resize((224, 224)), transforms.ToTensor()]) train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=128, shuffle=False) # 实例化ViT模型 model = ViT() # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) # 训练模型 num_epochs = 10 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device) for epoch in range(num_epochs): # 训练模式 model.train() train_loss = 0.0 train_acc = 0.0 for images, labels in train_loader: images, labels = images.to(device), labels.to(device) # 前向传播 outputs = model(images) loss = criterion(outputs, labels) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 统计训练损失和准确率 train_loss += loss.item() * images.size(0) _, preds = torch.max(outputs, 1) train_acc += torch.sum(preds == labels.data) train_loss = train_loss / len(train_loader.dataset) train_acc = train_acc
-
BertBERT,全称为“Bidirectional Encoder Representations from Transformers”,是一种预训练语言表示的方法,意味着我们在一个大型文本语料库(如维基百科)上训练一个通用的“语言理解”模型,然后将该模型用于我们关心的下游NLP任务(如问答)。BERT的表现优于之前的传统NLP方法,因为它是第一个用于预训练NLP的无监督的、深度双向系统。Bert是利用无标签方式建模的,当谈到NLP语料库中的无标签和有标签数据时,一个常见的例子是将文本分类任务。下面是一个例子:无标签数据:来自维基百科的大量文本,这些文本没有被人工标记或者标注。这些数据可以用来预训练语言模型,例如 BERT、GPT 等,以学习通用的语言表示形式。有标签数据:例如 IMDB 电影评论数据集,其中每个评论都被标记为正面或负面情感。这些数据可以用来训练文本分类器,使其能够自动对新的评论进行情感分类。Bert的无监督预训练方法非常重要,因为它允许我们在大规模文本语料库中进行训练,而无需为每个具体的NLP任务收集大量的有标签数据。由于网络上有大量的无标签文本数据,这种方法使得BERT可以利用这些数据来训练模型,提高模型在各种任务上的表现。与此同时,无监督预训练还能够提高模型对于语言的理解和表达能力。BERT的无监督预训练方法使得我们可以使用一个通用的"语言理解"模型,用于各种NLP任务,如问答、文本分类、实体识别等,而无需为每个任务重新训练一个新的模型。BERT 的主要任务是通过训练模型来预测文本序列中缺失的单词,因此模型只需要对输入的文本序列进行编码,而不需要对序列进行解码。他只用到了Transformer中的Encoder。Pre-training BERTPre-training BERT(Bidirectional Encoder Representations from Transformers)是一种基于大规模无标注文本数据的预训练方法,目的是为了训练出一个通用的语言模型,能够理解上下文语境中词语的语义信息。在BERT的预训练过程中,使用了两个阶段的训练方式:Masked LM和Next Sentence Prediction。(1)Masked LM(MLM)Masked Language Modeling (MLM) 是 BERT 模型的一种预训练方法,通过将输入文本中的某些单词随机地替换成特殊的 [MASK] 标记,使模型在预测被替换的单词时需要依据上下文信息进行推断,从而学习到单词的上下文相关性。具体来说,对于输入文本中的每个单词,以一定的概率(比如15%)随机选择将其替换为 [MASK] 标记,然后将经过 [MASK] 标记处理后的文本输入给模型进行预测。在预测过程中,模型需要根据上下文信息猜测被 [MASK] 标记替换的单词。这样的预测任务可以促使模型学习到单词的上下文信息,从而提高下游任务的性能。例如,对于输入文本 "I went to the [MASK] to buy some apples",模型需要根据上下文信息猜测被 [MASK] 标记替换的单词是 "store","market","shop" 等。通过这样的预测任务,模型可以学习到 "store","market","shop" 在不同上下文中的含义和用法,从而提高下游任务(如文本分类、情感分析、问答等)的性能。因为采用上下文无关的方式进行建模,意味着模型不考虑单词在句子中的位置和上下文环境,而是将每个单词独立地编码为固定的向量表示。所以MLM是至关重要的,因为他学习了上下文的信息。(2)Next Sentence Prediction(NSP)Next Sentence Prediction (NSP) 是 BERT 中的另外一种预训练任务,用于训练模型学习句子之间的关系。它的目标是判断两个句子是否是相邻的,即判断一个句子是否是另一个句子的下一句。NSP 的训练过程中,对于每一对输入的句子,有一半是相邻的,另一半是随机选择的不相邻的句子。模型需要对这两种情况进行分类预测。这个任务主要是为了帮助模型学习更好的语义表示,尤其是对于需要理解多个句子之间关系的任务,如问答和文本推理。输入的文本会被分成多个token,每个token会被映射为一个向量表示,这个向量表示就被称为token embedding。除了token embedding之外,BERT还有另外两种embedding,分别是sentence embedding和positional embedding。Sentence embedding是对整个句子进行编码得到的向量表示。在BERT中,对于输入的句子对(比如问答场景下的问题和回答),BERT会将句子对之间的特殊标记“[SEP]”添加到中间,并在整个输入序列的开头添加另一个特殊标记“[CLS]”。然后,整个序列的第一个token对应的向量就是整个句子的sentence embedding。Positional embedding则是用来表示每个token在句子中的位置信息。由于Transformer并不保留输入中token的位置信息,因此需要在输入的token embedding中加入位置信息,使得Transformer能够捕捉到句子中token的位置信息。这里采用了一种相对位置编码的方式,将每个token与其他token的相对位置信息编码成一个向量,然后将该向量加到该token的embedding中。在BERT中,这三种embedding会被拼接在一起,然后送入Transformer进行编码。这些编码代表了符号句子位置的特征。通过使用 MLM 和 NSP 两个任务来预训练模型,BERT 能够学习到更加丰富的语言表示,这些表示可以在各种 NLP 任务中进行微调。Fine-tuning BERTFine-tuning BERT是指在使用预训练的BERT模型后,将其进一步调整以适应特定任务的过程。这个过程可以理解为在BERT的基础上进行微调以使其更加适合完成特定的自然语言处理(NLP)任务。Fine-tuning BERT的主要步骤如下:准备数据集:根据特定的NLP任务,准备相应的数据集,包括训练集、验证集和测试集。定义任务:根据任务类型,选择适当的BERT模型和Fine-tuning策略。对于分类任务,可以使用BERT的CLS向量来表示整个句子,并通过添加一个全连接层来预测标签。对于序列标注任务,可以在BERT的基础上添加一个序列标注层。Fine-tuning:将准备好的数据集输入BERT模型进行Fine-tuning。在Fine-tuning过程中,对BERT模型的参数进行微调,以适应特定的NLP任务。通常使用反向传播算法进行模型优化。模型评估:使用验证集评估Fine-tuning后的模型性能,可以根据验证集的性能调整Fine-tuning策略或BERT模型的超参数。最终,使用测试集评估模型的性能。需要注意的是,Fine-tuning BERT需要大量的计算资源和时间,因为BERT模型本身具有非常多的参数和复杂的结构。此外,Fine-tuning BERT的性能还取决于任务的复杂性、数据集的质量和模型的选择等因素。代码实现下面是使用PyTorch实现Bert模型的示例代码,包括模型定义、数据预处理、模型训练和推理:import torch import torch.nn as nn import torch.optim as optim import torch.utils.data as data import transformers # 1. 定义Bert模型 class BertModel(nn.Module): def __init__(self, bert_config): super(BertModel, self).__init__() self.bert = transformers.BertModel(bert_config) self.dropout = nn.Dropout(bert_config.hidden_dropout_prob) self.fc = nn.Linear(bert_config.hidden_size, num_classes) def forward(self, input_ids, attention_mask): output = self.bert(input_ids=input_ids, attention_mask=attention_mask) output = output[1] # 取第1个tensor作为CLS向量 output = self.dropout(output) output = self.fc(output) return output # 2. 数据预处理 # 数据集包含输入序列和对应的标签 inputs = ["I love Python programming.", "Python is a high-level programming language."] labels = [0, 1] # 0表示第1个句子不是关于Python编程的,1表示第2个句子是关于Python编程的 tokenizer = transformers.BertTokenizer.from_pretrained('bert-base-uncased') max_seq_length = 64 # 输入序列最大长度 inputs_ids = [] attention_masks = [] for input_text in inputs: # 将文本转换为ids和attention mask encoded_dict = tokenizer.encode_plus( input_text, add_special_tokens=True, max_length=max_seq_length, pad_to_max_length=True, return_attention_mask=True, return_tensors='pt' ) inputs_ids.append(encoded_dict['input_ids']) attention_masks.append(encoded_dict['attention_mask']) inputs_ids = torch.cat(inputs_ids, dim=0) attention_masks = torch.cat(attention_masks, dim=0) labels = torch.tensor(labels) # 3. 定义超参数和优化器 num_classes = 2 learning_rate = 2e-5 num_epochs = 3 batch_size = 2 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = BertModel(transformers.BertConfig.from_pretrained('bert-base-uncased')).to(device) optimizer = optim.Adam(model.parameters(), lr=learning_rate) # 4. 定义数据加载器 dataset = data.TensorDataset(inputs_ids, attention_masks, labels) dataloader = data.DataLoader(dataset, batch_size=batch_size, shuffle=True) # 5. 训练模型 model.train() for epoch in range(num_epochs): for i, (input_ids_batch, attention_masks_batch, labels_batch) in enumerate(dataloader): input_ids_batch = input_ids_batch.to(device) attention_masks_batch = attention_masks_batch.to(device) labels_batch = labels_batch.to(device) optimizer.zero_grad() outputs = model(input_ids_batch, attention_masks_batch) loss = nn.CrossEntropyLoss()(outputs, labels_batch) loss.backward() optimizer.step() if i % 10 == 0: print(f"Epoch {epoch}, batch {i}, loss: {loss.item()}") # 6. 模型推理 model.eval() test_input = "Python is a popular programming language." encoded_dict = tokenizer.encode_plus( test_input, add_special_tokens
-
将txt文件的内容逐行读取转化成数组例:将train5bottle.names的每行内容提取出来转化成数组转换代码:1234567891011result = [] with open(r'E:\HISI\darknet-master\build\darknet\x64\data\train5bottle.names' ,'r') as f: for line in f: result.append(line.strip().split(',')[0]) #a.append(b):是将b原封不动的追加到a的末尾上,会改变a的值 #strip()用于移除字符串头尾指定的字符(默认为空格或者换行符)或字符序列 print(result) print(result[0])#运行结果:['0degree', '6degree', '12degree', '18degree', '24degree', '30degree', '36degree', '42degree', '48degree', '54degree', '60degree', '66degree', '72degree', '78degree', '84degree', '90degree', '96degree', '102degree', '108degree', '114degree', '120degree', '126degree', '132degree', '138degree', '144degree', '150degree', '156degree', '162degree', '168degree', '174degree', '180degree']0degree将srt文件转化成数组形式原srt文件000:00:00,150 --> 00:00:11,430Fighting this pandemic needs political commitment and commitment at the highest level possible and the President's commitment.100:00:11,431 --> 00:00:16,020you have what it is in it and the would it have seen it.200:00:16,021 --> 00:00:19,320and that kind of leadership is very,300:00:19,321 --> 00:00:20,160very important.400:00:20,161 --> 00:00:21,570The whole of government approach.转化之后的数组(将时间和内容分离)['00:00', '00:11', '00:16', '00:19', '00:20']["Fighting this pandemic needs political commitment and commitment at the highest level possible and the President's commitment.", 'you have what it is in it and the would it have seen it.', 'and that kind of leadership is very,', 'very important.', 'The whole of government approach.']下面贴出转化的代码,即将cte_test.srt转化成数组之后可以考虑输送到mysql数据库上进行复用123456789101112131415161718count1 = 1count2 = 2ktime = []klrc = []with open('cte_test.srt', 'r') as f: for index, value in enumerate(f.readlines()): if index==count1: value= value.strip()[3:8] ktime.append(value) count1=count1+4 elif index==count2: value= value.strip() klrc.append(value) count2=count2+4print(ktime)print(klrc)转载自https://www.jb51.net/article/278980.htm
-
python取反操作符~ : 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。~x 类似于 -x-11、计算依据①正数的原码、反码、补码都是一样的②负数的补码为符号位不变,剩余位取反再加1③原码求补码: 取反,+1④补码求原码: 取反,+1⑤负数是以补码存储的⑥取反操作是在原码上进行的⑦符号位,1表示负数,0表示正数2、例子~(-2)首先你要知道 -2 在计算机里面的二进制形式,由⑤和②可知:-2 原码:1000 0000 0000 0010-2 反码:1111 1111 1111 1101 #符号位不变,各位求反-2 补码:1111 1111 1111 1110 #补码 = 反码 + 11111 1111 1111 1110 就是-2在计算机里面的原型现在开始对他求反,符号位不变,按位取反: 0000 0000 0000 0001很明显是一个正数,其原码为其本身,所以输出为1.~22 原码,反码,补码: 0000 0000 0000 0010按位取反: 1111 1111 1111 1101这是一个负数该怎么办?能直接求吗?很显然是不行的,⑥说了:取反操作计算结果是在原码上进行的,⑤也说了:负数是以补码存储的1111 1111 1111 1101 是 0000 0000 0000 0010 的反码,但我们想要的是结果,而不是在计算机里面的原型,恰好,④补码求原码: 取反,+1取反: 1000 0000 0000 0010加 1: 1000 0000 0000 0011于是,我们得到了原码,可以计算结果了1000 0000 0000 0011 = -3总之,取反很简单,但是要注意,取反后是不是原码,是否可以直接计算结果python数值取反问题~在python中,用取反符号~得到的并不是我们想象中的结果,总结一下规律,就是 (取反后的值)= -(取反前的值)-1下面来分析一下例如对1取反,1的8位二进制表示为:0000 0001 , 取反后的结果是:1111 1110, 对于计算机来说,二进制以1开头表示的是负数, 所以这个1111 1110到底表示的是什么负值呢,想要知道这个值,可以求它的补码,即先取反码 :0000 0001, 再加1:0000 0010,说明 1111 1110 的原码为 0000 0010 也就是正数 2, 所以 1111 1110代表的就是负数 -2 下面再举个例如对 -2 取反, -2的二进制表示为 2的补码,即 0000 0010 > 1111 1101 > 1111 1110 ,-2的二进制就表示为1111 1110, 对它取反得到 0000 0001,显而易见,取反后的值为1 , 所以 ~(-2)= 1 , ~1=-2总结出来就是:(取反后的值)= -(取反前的值)-1转载自https://www.jb51.net/article/278982.htm
-
以下内容均为个人笔记,仅供学习参考使用,因内容均为自己实践经验所得,个人水平有限,如有错误欢迎指正 注:编程语言为Python3 1.get()函数利用键来获取值 之前在学习python的时候,在获取值得时候常用的方法就是直接 print(dict[key]) 1 但这种方法中当字典中不存在该键时会返回KeyError类型错误,此时就可以用get()函数还利用键获取值 print(dict.get(key)) 1 利用get()函数操作时当字典中不存在输入的键时会返回一个None,这样程序运行时就不会出异常 2.利用字典统计列表中元素出现次数 比如现在有这么一个列表,让你统计列表中部分元素出现的次数 ls=['aa','b','c','ddd','aa'] 1 统计列表中每个元素出现次数: cou={} #创建一个空字典 for i in ls: cou[i]=cou.get(i,0)+1 #之后称其为get的赋值语句,目的是新建字典键值对 ''' 赋值语句代码等价于 cou[i]=0 cou[i}=cou[i]+1 ''' print(cou) 输出结果: {'aa': 2, 'b': 1, 'c': 1, 'ddd': 1} 1 get()函数在这里有两个参数,第一个是确定要分配值的键,第二个是拟定给键分配一个初值,但实际要给键赋值仍需要get赋值语句(为什么这么说下面有介绍) 比如说我现在添加这个语句到代码中 cou.get('b',10) #之后称为拟定初值语句 1 拟定初值语句本身对结果是没有影响的,因为并没有实际的对键进行赋值语句操作(个人感觉拟定初值语句是因为没有在字典中找到要赋值的键,因为根本没有创建要赋值的键,因此赋值失败,即相当于一个没有返回值的函数,就算给这个函数赋参数了也没有任何返回结果) 注:get()函数在作为键赋值语句(非拟定赋值语句,区别看上代码框内注释)时只有第一次是有效的,(比如get()函数在第一次对’aa’这个键使用get赋值语句后下次再使用get赋值语句时键的值仍为第一次赋值运算后的结果),以下为测试代码: ls=['aa','b','c','ddd','aa'] cou={} #创建一个空字典 for i in ls: cou[i]=cou.get(i,0)+1 #功能逻辑看下方阐述 cou['aa']=cou.get('aa',10) #功能同前一条代码执行到第二次时的 print(cou) 这里着重讲一下第4行代码:cou[i]=cou.get(i,0)+1 第行代码从逻辑上讲执行了两次,而这两次里get语句每次执行时的功能是不一样的: 第一次:cou[i]=cou.get(i,0)+1(i=‘aa’) 此时get语句的功能为赋初值,即把键’aa’的初值置为0然后加1 第二次:cou[i]=cou.get(i,0)+1(i=‘aa’) 因get语句已经作为赋值语句出现过一次了,因此此时再执行这条语句时,赋值功能已经无效了,也就是get语句里第二个参数对’aa’这个键已经无效了,此时get语句的功能为文章内的第一大部分所介绍的功能,所以这条语句此时可等价为 cou[i]=cou.get(i)+1 即 cou[i]=cou[i]+1 输出结果和之前的代码结果相同: {'aa': 2, 'b': 1, 'c': 1, 'ddd': 1} 当单独使用get赋值语句时如果键是第一次出现的话,效果等同赋值语句(和之前在空字典里通过for循环建立新键值对效果一样) cou['e']=cou.get(e,10) 输出结果: ```python {'aa': 10, 'b': 1, 'c': 1, 'ddd': 1,'e':10} 顺带一提如果想直接改变字典中键的值时可用如下方法: cou['aa']=10 #这种赋值语句带有强制性 print(cou) 输出结果: {'aa': 10, 'b': 1, 'c': 1, 'ddd': 1} ———————————————— 版权声明:本文为CSDN博主「百万雨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/aaa9692/article/details/115469795
推荐直播
-
华为云码道 × 仓颉编程:工程化AI编码探索2026/05/27 周三 19:00-21:00
刘俊杰-华为云仓颉语言专家/李炎-华为云码道技术专家/王智鹏-OpenCangjie开源社区发起人
本场直播围绕华为云仓颉语言与华为云码道的深度结合,展示华为云智能编程从零基础到高效落地的完整生态能力。以华为云码道为引擎,仓颉语言为载体,带给大家日常提效、趣味创新到极速量产的开发体验。
回顾中
热门标签