MQ介绍

一、 为什么要用MQ 传统生产者调用消费者使用的是RPC的调用模式,应用于应用之间耦合度极高 消息队列是一种“先进先出”的数据结构,生产者将消息放到消息队列中,消费者再从队列中取出消息 其应用场景主要包含以下3个方面 应用解耦 系统的耦合性越高,容错性就越低。以电商应用为例,用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障或者因为升级等原因暂时不可用,都会造成下单操作异常,影响用户使用体验。 使用消息队列解耦合,系统的耦合性就会提高了。比如物流系统发生故障,需要几分钟才能来修复,在这段时间内,物流系统要处理的数据被缓存到消息队列中,用户的下单操作正常完成。当物流系统恢复后,补充处理存在消息队列中的订单消息即可,终端系统感知不到物流系统发生过几分钟故障。 流量削峰 应用系统如果遇到系统请求流量的瞬间猛增,有可能会将系统压垮。有了消息队列可以将大量请求缓存起来,分散到很长一段时间处理,这样可以大大提到系统的稳定性和用户体验。 一般情况,为了保证系统的稳定性,如果系统负载超过阈值,就会阻止用户请求,这会影响用户体验,而如果使用消息队列将请求缓存起来,等待系统处理完毕后通知用户下单完毕,这样总不能下单体验要好。 业务系统正常时段的QPS如果是1000,流量最高峰是10000,由于高峰是短暂的,为了应对流量高峰配置高性能的服务器显然不划算,这时可以使用消息队列对峰值流量削峰 数据分发 通过消息队列可以让数据在多个系统更加之间进行流通。数据的产生方不需要关心谁来使用数据,只需要将数据发送到消息队列,数据使用方直接在消息队列中直接获取数据即可。同步的方式,新增或者删除系统都需要修改源代码。 MQ作用总结 解耦: 不同功能模块之间是相互依赖的关系,如果下订单的时候,物流系统宕机,则会出现下订单失败的情况使用消息队列,将物流系统原本要处理的工作存储起来,等待恢复后再进行处理,可以避免订单的失败 流量削峰: 当上线一个功能,比如商品的秒杀业务,会短时间有大量的请求访问,有可能会将系统压垮,导致订单失败通过硬件支持短时间的巨量QPS,是十分不经济的消息队列可以将订单请求存储分散在一个较长的时间处理,等待处理完毕再通知用户,既减轻了系统的压力,也避免了下单失败的情况 数据分发 当各个系统之间采用同步的方式进行调用,如果此时增减或者减少一个系统,需要修改源代码利用消息队列,数据的产生方不需要关注谁来使用数据,数据使用方只需要订阅或者取消订阅消息队列即可 二、 MQ的优点和缺点 优点:解耦、削峰、数据分发 缺点包含以下几点: 如何保证MQ的高可用? 系统引入的外部依赖越多,系统稳定性越差。一旦MQ宕机,就会对业务造成影响。 系统复杂度提高,如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性? MQ的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过MQ进行异步调用。 如何保证消息数据处理的一致性? A系统处理完业务,通过MQ给B、C、D三个系统发消息数据,如果B系统、C系统处理成功,D系统处理失败。 三、 各种MQ产品的比较 常见的MQ产品包括Kafka、ActiveMQ、RabbitMQ、RocketMQ。

lvm 挂载硬盘

在做了给根分区扩容(https://blog.csdn.net/qq_39314099/article/details/106358035)后,对lvm有了一点了解,于是准备重新添加硬盘,使用lvm挂载方式挂载。 首先,lvm挂载过程大致是,创建物理卷PV -> 创建卷组 VG -> 创建逻辑卷LV -> 格式化 -> 挂载。 具体操作过程如下: 添加两块10g硬盘: sdc、sdd就是新添加的硬盘。分区: 将sdd也进行同样处理: fdisk /dev/sdd >>> p 查看分区表 >>> n 创建新分区 >>> p 选择主分区 >>> 回车三次,分区号,扇区号都默认 >>> p 查看分区表 >>> t 修改分区类型 >>> 8e 分区类型改为 LVM >>> w 保存 这是创建好的分区,接下来需要对这些分区来进行创建物理卷PV等操作。 分完区如果用lsblk命令看不到变化,可以重新读取分区表 partprobe 创建物理卷PV: pvcreate /dev/{sdc1,sdd1} 如果没有创建分区,那么这里使用的应该是磁盘的符号 /dev/{sdc,sdd},由于我已经创建分区,所以使用的是分区的符号 /dev/{sdc1,sdd1} 如果创建的时候,提示被排除了。可能之前在这个设备上存在过分区表信息。 擦除即可: 创建成功,现在它们还没有所属的卷组,接下来创建卷组 创建卷组VG: vgcreate vgdata /dev/{sdc1,sdd1} 这里的data是给创建的新卷组起的名字 创建成功后,接下来创建逻辑卷LV创建逻辑卷LV: lvcreate -l 100%VG -n lvdata vgdata -l:指定逻辑卷大小,我使用了100%的卷组。 -n:指定创建的逻辑卷名字。 最后跟的 vgdata 是卷组的名字

Nginx 的过滤模块是干啥用的?

上一篇文章我写了 Nginx 的 11 个阶段,很多人都说太长了。这是出于文章完整性的考虑的,11 个阶段嘛,一次性说完就完事了。今天这篇文章比较短,看完没问题。 过滤模块的位置 之前我们介绍了 Nginx 的 11 个阶段,在 content 阶段时,Nginx 会生成返回给用户的响应内容,对用户的响应内容,实际上还需要做再加工处理,Nginx 的过滤模块就是对响应内容进行再加工处理的。所以实际上过滤模块位于 content 阶段之后,log 阶段之前。 我们先来看一段配置指令: limit_req zone=req_one burst=120; limit_conn c_zone 1; satisfy any; allow 192.168.1.0/32; auth_basic_user_file access.pass; gzip on; image_filter resize 80 80; 那么在这一段配置指令之下,会遵循怎样的请求流程呢?请看一下下面这张图: 上面这张图的流程大致说一下,如果对于 Nginx 的 11 个阶段不了解的去翻一下之前的文章。 我这里再简单说一下。首先由 Nginx 框架接收 HTTP 请求,经过 preaccess、access、content 阶段的处理,当经过 static 模块之后生成响应的时候,很多时候需要对响应进行处理,然后才会返回给客户端。 这里我们假如响应是一张图片的话,那么需要做缩略图的时候,首先就要经过 image_filter 模块的处理。这里面还有一个 gzip 模块,这两个模块也是需要遵循严格的顺序的。因为如果先做 gzip 压缩的话,缩略图后面就没办法做了。 第二个需要关注的地方是,首先对 header 进行过滤,再对 body 进行过滤。因为我们在对用户发送响应的时候,一定是先发送 header,然后再发送 body,所以所有的过滤模块都会提供对 header 或 body 的过滤,当然 image_filter 和 gzip 模块对这两者都可以过滤。

点云全局配准

国内外现状及问题 (1)4pcs,搜索的计算量太大,不适合工程化应用。 (2)sift特征,128维,维度太高得到的特征点太少,最要命的还不是搜索量大,而是计算出来的特征点太少,不适合重叠率低的对象。 (3)FPFH,方向直方图,spin image,都相当依赖于法线计算的准确性,需要建立局部坐标系,需要点云分布相对均匀,自己动手实现效果不佳,转而用开源的也不行,且不抗噪,维度过高搜索量大,维度低不具备区分性,这几个最低的维度33维,最高能过到一二百维。 (4)extend Gaussian image,也过份依赖法线和点云分布的均匀性而且只能算R,对于T还得另外想法办法(当然也有人提出了解决办法)。 (5)Rotational Projection Statistics国防科大的Yulan Guo,同(3)一样的 问题。 (6)依赖曲率的,用径向基函数拟合二次曲面,计算量大,不抗噪声。 除此之外,当然还有其它的如香港权龙教授。 自研算法 做这个算法花费了近一个月的时间,由于个人能力的限制,在这短短的一个月时间内能全部看懂和实现上述论文是不可能的(大概过了二三十篇文章),因此理解上可能有错误,导致效果不行。在总结了这些算法优劣的基础上,找到了一种全新的描述子,该描述子具备以下特性: (1)相当的稳健,相比其它具备更稳健的仿射变换不变性。 (2)使用了15维的描述,相较其它特征描述,维度相当的低。 (3)对点云分布无任何要求。 (4)抗噪表现良好(只是为了进一步的说明描述子的稳健,实际扫描点云不会出现这种 噪声的数据,使用了 Qinyi Zhou的噪声数据集进行了测试) 效果图 对于一般的情况下的数据,表现相当优秀,下面给出几组测试结果: (1)不同的采样点数 (2)不同的重叠率 (3)不同特征的数据(即特征是否明显) 图4.1 小天使原始数据 为了说明本方法满足上述特性,使用GeoMagic对待配准的原始数据集进行不同点数的采样,采样点数分别为5000个点和20000个点,由于原始数据点云数量不同,所能表征点云的表面积也不同,使用固定点数对待配准的两个数据进行采样,得到的点云的密度也将会有差异,从而对应的点距也存在差异,满足上述所述特性。 图4.2小天使5000点 说明由于使用的是Geomagic的固定点数采样,所以采样点数只是接近预计点数。 图4.3小天使5000点配准结果(Validated Pairwise:477) 4.1.2小天使采样20000个点全局配准 图4.4小天使20000点 图4.5小天使20000点配准结果(Validated Pairwise:3105) 图4.14 空间零散原始数据 图4.16空间零散数据5000点配准结果(Validated Pairwise:151) 极端情况 图4.6 大天使原始数据 图4.7大天使5000点 图4.8 大天使5000点配准结果(Validated Pairwise:130)配准失败 图4.8-a 大天使5000点(更改参数后)配准结果(Validated Pairwise:196)配准成功 目前测试结果:对于正常扫描件还未出现问题表现良好,可以给ICP很好的初值,只有自设的这些特征不明显的数据或者极端情况会存在问题,这个好像克服不了,因为特征不明显,换而言之每个点的相似度太高。

python多线程爬取ts文件并合成mp4视频

python多线程爬取ts文件并合成mp4视频 声明:仅供技术交流,请勿用于非法用途,如有其它非法用途造成损失,和本博客无关 目录 python多线程爬取ts文件并合成mp4视频前言一、分析页面二、整体思路逻辑三、开始编写代码四、一些技巧 写在最后 前言 在我看来,爬取视频可以分为简单、中等以及困难三种级别。 简单级别:网页直接给出了mp4格式的视频链接,所以可以像下载图片一样发个请求就可以轻松获得中等级别:就是网页给出的是ts文件,所有的ts文件会存储在一个m3u8文件中,我们请求这个m3u8文件即可拿到全部的ts文件的请求网址,然后把全部的ts都下载下来,最后再将它们合成一个mp4格式的视频就行困难级别:其实就是在中等级别的基础上,网站给出的m3u8文件不会明文给你看到所有的ts文件,而是会利用一些加密的算法,将其加密 那么,本文爬取视频的级别是中等。爬取的视频网址:点击跳转 废话不多说,下面直接开始吧 一、分析页面 首先打开开发者工具,可以看到每一集对应的url存在一个li的列表当中 然后点开到第一集视频播放页面,再次打开开发者工具,点击network之后刷新页面,可以看到在第二个m3u8文件中出现了所有的ts文件,那么,这就是我们要找的东西了,只是这个ts文件的网址不全 再看看第一个m3u8的文件响应中有1024k/hls/index.m3u8这么个字符串,可以知道,这个其实是第二个m3u8文件网址的末尾部分,并且ts文件网址也只是修改了第二个m3u8文件的末尾而已。ok,到这里已经知道全部的ts文件网址了,只要拿到第一个m3u8文件的网址即可。 第一个m3u8:https://mojing.huoyanzuida.com/20200424/2487_d0fc7191/index.m3u8 第二个m3u8:https://mojing.huoyanzuida.com/20200424/2487_d0fc7191/1024k/hls/index.m3u8 第一个ts:https://mojing.huoyanzuida.com/20200424/2487_d0fc7191/1024k/hls/33a92401b72000000.ts 接下来,就是要找出第一个m3u8跟之前的网址存在什么联系,首先全局搜索一下“m3u8”,发现在5014.js这个文件中发现了一个用base64加密了的字符串, 将其解密之后得到: %u7b2c01%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2487_d0fc7191%2Findex.m3u8%23%u7b2c02%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2484_640df7e0%2Findex.m3u8%23%u7b2c03%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2490_0b2ee7ab%2Findex.m3u8%23%u7b2c04%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2485_029c4007%2Findex.m3u8%23%u7b2c05%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2486_957bb1f3%2Findex.m3u8%23%u7b2c06%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2488_06dae5ae%2Findex.m3u8%23%u7b2c07%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2497_4350d451%2Findex.m3u8%23%u7b2c08%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2489_677b9744%2Findex.m3u8%23%u7b2c09%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2495_3e03853a%2Findex.m3u8%23%u7b2c10%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2491_de7cb550%2Findex.m3u8%23%u7b2c11%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2492_e8221393%2Findex.m3u8%23%u7b2c12%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2493_5b52e7e5%2Findex.m3u8%23%u7b2c13%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2494_8ebe1863%2Findex.m3u8%23%u7b2c14%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2496_a814c3b3%2Findex.m3u8%23%u7b2c15%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2500_cafb68ab%2Findex.m3u8%23%u7b2c16%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2498_9e696bf2%2Findex.m3u8%23%u7b2c17%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2499_0015700c%2Findex.m3u8%23%u7b2c18%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2502_c39cb88d%2Findex.m3u8%23%u7b2c19%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2501_c12a81f8%2Findex.m3u8%23%u7b2c20%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2503_5fd7c956%2Findex.m3u8%23%u7b2c21%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2553_5efba16b%2Findex.m3u8%23%u7b2c22%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2510_41b6e254%2Findex.m3u8%23%u7b2c23%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2508_92bd89a2%2Findex.m3u8%23%u7b2c24%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2504_02863479%2Findex.m3u8%23%u7b2c25%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2505_45f36385%2Findex.m3u8%23%u7b2c26%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2506_307718a8%2Findex.m3u8%23%u7b2c27%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2507_2d365300%2Findex.m3u8%23%u7b2c28%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2509_2c9d20a5%2Findex.m3u8%23%u7b2c29%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2512_47a6b558%2Findex.m3u8%23%u7b2c30%u96c6%24https%3A%2F%2Fmojing.huoyanzuida.com%2F20200424%2F2511_da5c4e6f%2Findex.m3u8 然后在通过urllib.parse.unquote方法解析得到: b'%u7b2c01%u96c6$https://mojing.huoyanzuida.com/20200424/2487_d0fc7191/index.m3u8#%u7b2c02%u96c6$https://mojing.huoyanzuida.com/20200424/2484_640df7e0/index.m3u8#%u7b2c03%u96c6$https://mojing.huoyanzuida.com/20200424/2490_0b2ee7ab/index.m3u8#%u7b2c04%u96c6$https://mojing.huoyanzuida.com/20200424/2485_029c4007/index.m3u8#%u7b2c05%u96c6$https://mojing.huoyanzuida.com/20200424/2486_957bb1f3/index.m3u8#%u7b2c06%u96c6$https://mojing.huoyanzuida.com/20200424/2488_06dae5ae/index.m3u8#%u7b2c07%u96c6$https://mojing.huoyanzuida.com/20200424/2497_4350d451/index.m3u8#%u7b2c08%u96c6$https://mojing.huoyanzuida.com/20200424/2489_677b9744/index.m3u8#%u7b2c09%u96c6$https://mojing.huoyanzuida.com/20200424/2495_3e03853a/index.m3u8#%u7b2c10%u96c6$https://mojing.huoyanzuida.com/20200424/2491_de7cb550/index.m3u8#%u7b2c11%u96c6$https://mojing.huoyanzuida.com/20200424/2492_e8221393/index.m3u8#%u7b2c12%u96c6$https://mojing.huoyanzuida.com/20200424/2493_5b52e7e5/index.m3u8#%u7b2c13%u96c6$https://mojing.huoyanzuida.com/20200424/2494_8ebe1863/index.m3u8#%u7b2c14%u96c6$https://mojing.huoyanzuida.com/20200424/2496_a814c3b3/index.m3u8#%u7b2c15%u96c6$https://mojing.huoyanzuida.com/20200424/2500_cafb68ab/index.m3u8#%u7b2c16%u96c6$https://mojing.huoyanzuida.com/20200424/2498_9e696bf2/index.m3u8#%u7b2c17%u96c6$https://mojing.huoyanzuida.com/20200424/2499_0015700c/index.m3u8#%u7b2c18%u96c6$https://mojing.huoyanzuida.com/20200424/2502_c39cb88d/index.m3u8#%u7b2c19%u96c6$https://mojing.huoyanzuida.com/20200424/2501_c12a81f8/index.m3u8#%u7b2c20%u96c6$https://mojing.huoyanzuida.com/20200424/2503_5fd7c956/index.m3u8#%u7b2c21%u96c6$https://mojing.huoyanzuida.com/20200424/2553_5efba16b/index.m3u8#%u7b2c22%u96c6$https://mojing.huoyanzuida.com/20200424/2510_41b6e254/index.m3u8#%u7b2c23%u96c6$https://mojing.huoyanzuida.com/20200424/2508_92bd89a2/index.m3u8#%u7b2c24%u96c6$https://mojing.huoyanzuida.com/20200424/2504_02863479/index.m3u8#%u7b2c25%u96c6$https://mojing.huoyanzuida.com/20200424/2505_45f36385/index.m3u8#%u7b2c26%u96c6$https://mojing.huoyanzuida.com/20200424/2506_307718a8/index.m3u8#%u7b2c27%u96c6$https://mojing.huoyanzuida.com/20200424/2507_2d365300/index.m3u8#%u7b2c28%u96c6$https://mojing.huoyanzuida.com/20200424/2509_2c9d20a5/index.m3u8#%u7b2c29%u96c6$https://mojing.huoyanzuida.com/20200424/2512_47a6b558/index.m3u8#%u7b2c30%u96c6$https://mojing.huoyanzuida.com/20200424/2511_da5c4e6f/index.m3u8' 可以清楚地看到其中具体的网址了,并且可以看到第一个网址正是我们第一个m3u8文件的网址,并且还发现了,这里包含了这个电视剧所有集数的m3u8文件网址,这就太棒了,不用去请求每一集来获取m3u8文件了。不过还没有完,就是这个5014.js的文件网址要去那里找呢?正是在视频播放页的网页源代码当中: 二、整体思路逻辑 1,首先在视频播放页的网页源代码中拿到那个js文件,接着请求这个js,拿到其响应中的通过base64加密的字符串 2,然后解密这个字符串,拿到所有集数的第一个m3u8文件网址,接着通过两个m3u8文件之间存在的关系,拿到所有集数的第二个m3u8文件网址,也就是用来保存所有ts文件的那个m3u8 3,再通过m3u8和ts这两个网址之间的关系,拿到所有的对应集数的全部的ts文件网址 4,最后,就可以通过Python多线程将它们下载下来,并合成mp4视频 三、开始编写代码 # 导入相关包或模块 import threading, queue import time, os, subprocess import requests, urllib, parsel import random, re, base64 # 拿到播放页网址 def get_bofangye_url(url): r=requests.get(url,headers=headers) response=parsel.Selector(r.text) bofangye_url='https://www.dsm8.cc' + response.xpath('//div[@id="vlink_1"]/ul/li/a/@href').get() return bofangye_url # 拿到js文件网址 def get_js_url(bofangye_url): r=requests.get(bofangye_url,headers=headers) response=parsel.Selector(r.text) js_url='https://www.dsm8.cc'+response.xpath('//div[@id="flash"]/script/@src').get() return js_url # 拿到所有的m3u8文件网址 def get_all_url(js_url): r=requests.

一文看懂HBase倒序分页查询(实现分页跳转)

HBase倒序分页查询 HBase分页方式Hbase倒序查询HBase分页思想HBase分页具体代码POM文件java类 HBase分页方式 HBase分页查询常见的方式有两种,一种是只能点击下一页上一页,不支持跳转到某一页,而另一种则是可以点击上一页下一页,同时也可以选择跳转到某个指定的页面。我们这篇完成的例子是第二种分页方式,可跳转到某个页面。 Hbase倒序查询 Hbase实现倒序查询非常简单,只需将扫描器设置为倒序扫描即可。 // 设置倒序扫描(倒序查询的关键) scan.setReversed(true); HBase分页思想 HBase分页的核心思想就是结合rowkey比较过滤器(RowFilter)和分页过滤器 (PageFilter)进行查询 分页过滤器 (PageFilter) 使用这个过滤器可以实现对结果按行进行分页,在创建PageFilter实例的时候需要传入每页的行数。 RowKey比较过滤器(RowFilter) 使用这个过滤器可以实现对查询数据根据rowkey进行比较,比较的规则和比较的rowkey在创建RowFilter实例时传入。 首先我们需要配置PageFilter,设置我们每一页需要查询的条数 // 设置查询条数 PageFilter pageFilter = new PageFilter(pageSize); 配置完了分页过滤器之后,我们需要创建一个RowFilter // 创建RowFilter RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.LESS, new BinaryComparator(Bytes.toBytes(startRowKey))); 在创建RowFilter我们传入了两个参数: 第一个参数是比较运算符CompareFilter.CompareOp.LESS表示小于; 第二个参数是比较器new BinaryComparator(Bytes.toBytes(startRowKey))表示使用Bytes.compareTo(byte [],byte [])按字典序进行比较。 所以到这里就能明白,上面创建的rowFilter代表的含义,即使用Bytes.compareTo(byte [],byte [])方式按照字典顺序获取数据中rowkey比startRowKey小的数据。 这里为什么使用小于呢,因为我们本篇使用的是倒序查询。比较运算符和比较器需要结合实际的需求来决定,而不是固定的 HBase分页具体代码 POM文件 <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-server</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-common</artifactId> <version>1.3.1</version> </dependency> java类 package com.xiaoming.springboot.util.hbase; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.conf.Configuration; import org.

4.1.4 OS之文件的物理结构(连续分配、链接分配[隐式-显式]、索引分配[链接方案-多层索引-混合索引])

文章目录 0.思维导图1.文件块、磁盘块2.连续分配3.链接分配隐式链接显式链接链接分配总结 4.索引分配链接方案多层索引混合索引索引分配总结 5.文件物理结构分配总结 0.思维导图 1.文件块、磁盘块 2.连续分配 连续分配优点: 连续分配缺点: 3.链接分配 隐式链接 显式链接 链接分配总结 4.索引分配 如何实现逻辑块号到物理块号的转换? 数据太大,一个索引表装不下那么多的映射怎么办? 链接方案 多层索引 混合索引 索引分配总结 5.文件物理结构分配总结 参考:《王道操作系统》

数据预处理Part4——数据离散化

文章目录 离散化,对数据做逻辑分层1. 什么是数据离散化?2. 为什么要将数据离散化3. 如何将数据离散化?3.1 时间数据离散化3.2 多值离散数据离散化3.3 连续数据离散化3.4 连续数据二值化 离散化,对数据做逻辑分层 1. 什么是数据离散化? 所谓离散化,就是把无限空间中有限的个体映射到有限的空间中。数据离散化操作大多是针对连续数据进行的,处理之后的数据值域分布将从连续属性变为离散属性,这种属性一般包含2个或2个以上的值域。 2. 为什么要将数据离散化 节约计算资源,提高计算效率算法模型的计算需要。虽然很多模型,例如决策树可以支持输入连续型数据,但是决策树本身会先将连续型数据转化为离散型数据,因此离散化转换是一个必要步骤。增强模型的稳定性和准确度。数据离散化之后,处于异常状态的数据不会明显的突出异常特征,而是会被划分为一个子集中的一部分。如10000为异常值,可以划分为>100。因此异常数据对模型的影响会大大降低,尤其是基于距离计算的模型效果更明显。特定数据处理和分析的必要步骤,尤其是在图像处理方面应用广泛。大多数图像做特征检测时,都需要先将 图像做二值化处理,二值化也是离散化的一种。模型结果应用和部署的需要。如果原始数据的值域分布过多,或者值域划分不符合业务逻辑,俺么模型结果将很难被业务理解并应用。以银行信用卡评分距离,在用户填写表单时,不可能填写年收入为某个具体数字如100万,而是填写薪资位于哪个范围,这样从业务上来说才是可行的。 3. 如何将数据离散化? 3.1 时间数据离散化 针对时间数据的离散化主要用于以时间为主要特征的数据集中和粒度转换,离散化处理后将分散的时间特征转为更高层次的时间特征。 在带有时间的数据集中,时间可能作为行记录的序列,也可能作为列记录数据特征。常见的针对时间数据的离散化操作有以下两类: 针对一天中的时间离散化。一般是将时间戳转换为秒、分钟、小时或上下午。针对日粒度以上数据的离散化。一般是将日期转化为周数、周几、月、工作日或者休息日 针对时间数据的离散化可以将细粒度的时间序列数据离散化为粗粒度的3类数据: 离散化为分类数据,例如上午,下午离散化为顺序数据,例如周一、周二、周三等离散化为数值型数据,例如一年有52个周,周数是数值型数据 代码实现: [1]:import pandas as pd from sklearn.cluster import KMeans from sklearn import preprocessing [2]:df = pd.read_csv("data.txt",sep='\t',names=['id','amount','income','datetime','age']) [4]:df['datetime'] = pd.to_datetime(df['datetime']) df["weekday"] = [i.weekday() for i in df["datetime"]] 3.2 多值离散数据离散化 针对多值离散数据的离散化指的是要进行离散化处理的数据本身不是数值型数据,而是分类或顺序数据。 多值离散数据要进行离散化还有可能是划分的逻辑有问题,这一般是由业务逻辑影响的。例如,用户价值原来为高价值、中价值、低价值,现在要变为高价值、中价值、低价值和负价值。此时就需要对不同类别的数据进行统一规则的离散化处理。 代码实现: [6]:map_df = pd.DataFrame( [['0-10', '0-40'], ['10-20', '0-40'], ['20-30', '0-40'], ['30-40', '0-40'], ['40-50', '40-80'], ['50-60', '40-80'], ['60-70', '40-80'], ['70-80', '40-80'], ['80-90', '>80'], ['>90', '>80']],columns=['age', 'age2']) # 定义一个要转换的新区间 df_tmp = df.

目标检测之—MTCNN实现人脸检测

摘要 MTCNN算法,这个算法可以将人脸检测和特征点检测结合起来,并且MTCNN的级联结构对现代的人脸识别也产生了很大的影响。本文为大家介绍MTCNN的算法原理和训练技巧,随后解析MTCNN算法的代码以及DEMO演示。论文地址。 一,原理 人脸检测,解决两个问题: 1)识别图片中有没有人脸? 2)如果有,人脸在哪?因此,许多人脸应用(人脸识别、特征分析)的基础是人脸检测。 MTCNN:(Multi-task Cascaded Convolutional Neural Networks) 翻译为: 多任务级联卷积神经网络,MTCNN在刚出来的时候是表现非常优秀的,目前已经不是最优的了,该网络的进步意义在于:第一次将人脸检测和人脸特征点定位结合起来,以及采用三个网络级联使用和图像金字塔缩放的思想。 (1)MTCNN侦测第一阶段 通过P-Net(Proposal Network),获得候选窗口和边界回归值。同时候选窗口根据边界框进行校正,再利用NMS(非极大值抑制)去除重复的候选框。 (2)MTCNN侦测第二阶段 经过PNet处理后的候选框输入到R-Net(Refine Network),RNet对这些候选的框体对应的图片进一步侦测,最后在卷积的最后一层使用全连接网络进行分类,然后再次使用NMS去除这时重复的候选框,留下部分候选框。 (3)MTCNN侦测第三阶段 O-net(Output Network)对上层网络输出的结果进行进一步的侦测,同样对这些重复的候选框使用了NMS,并最终输出各个候选框的置信度以及标定每个候选框中人脸的5个特征点。 以上只是三个级联网络的大致使用流程,其中涉及了很多图像变换操作,IOU,NMS的计算,而且三个网络的要求精度为:Onet >Rnet>Pnet。让我们直接上摘自论文的经典流程图: ​​ 可以看出,MTCNN网络在对单独一个人脸侦测过程是从最开始的输出很多候选框到最终确定为一个人脸框及5个特征点。 二、网络结构图 如下: 代码: import torch import torch.nn as nn """ 对网络结构进行了改进,Depthwise Conv""" class PNet(nn.Module): def __init__(self): super(PNet, self).__init__() self.pre_layer = nn.Sequential( nn.Conv2d(3, 8, 3, 1), nn.PReLU(), nn.MaxPool2d(2, 2), nn.Conv2d(8, 16, 3, 1, groups=4), nn.PReLU(), nn.Conv2d(16, 32, 3, 1, groups=8), nn.PReLU()) self.conv4_1 = nn.Conv2d(32, 1, kernel_size=1, stride=1) self.

与BSN的链码进行通信互动

在上一节完成链码部署后,就可以与链码进行通信互动了。互动有多种方式,如通过SDK编程,也可以使用peer节点使用命令行操作完成。本节先使用后者实现 预置链码包介绍 通过区块链服务网络开发者手册可知,BSN提供的预置链码包提供了五个方法,我们逐一来操作处理 1、增加数据(set) 输入参数说明 baseKey:需要保存的唯一的主键标识 baseValue:保存的数据信息 例:{"baseKey":"str","baseValue":"this is string"} 其中 baseKey 是不能为空的字符串,baseValue 可以是任意类型的数据。如果 baseKey 已经存在,则直接返回已经存在,不能添加;如果不存在,则添加数据。 2、获取数据(get) 输入参数说明 baseKey:需要获取的唯一的主键标识的值 例:str 其中 baseKey 的值不能为空,且必须存在,否则将无法获取到相应的信息。 3、修改数据(update) 输入参数说明 baseKey:需要修改的唯一的主键标识 baseValue:保存的数据信息 例:{"baseKey":"str","baseValue":"this is string"} 其中 baseKey 是不能为空的字符串,baseValue 可以是任意类型的数据。如果 baseKey 不存在,则无法更新,如果已经存在,则修改数据。 4、获取历史记录数据(getHistory) 输入参数说明 baseKey:需要获取的唯一的主键标识的值 例:str 其中 baseKey 的值不能为空。响应结果:交易 Id(txId)、交易时间(txTime)、是否删除(isDelete)、交易信息(dataInfo)。 5、删除数据(delete) 输入参数说明 baseKey:需要删除的唯一的主键标识的值 例:str 其中 baseKey 的值不能为空,且必须存在,否则将无法删除。 实操入门 1、增加数据(set) 按BSN官方给的手册,如果直接在命令里使用-c '{"Args":["set",{"baseKey":"str","baseValue":"this is string"}]}'的话,系统会报这个错误:Error: chaincode argument error: json: cannot unmarshal object into Go struct field .Args of type string,这是因为Fabric底层是使用golang语言开发,传的参数不能是对象,只能是字符串的格式,如'{"

freeswitch部署及网关调试

freeswitch部署及网关调试 目录 freeswitch部署及网关调试... - 1 - 一、freeswitch部署... - 3 - (一)基础部署... - 3 - (二)根据实际情况需求的部署配置... - 4 - 1、freeswitch开启支持音频和视频... - 4 - 2、配置联通/电信双线... - 5 - 3、防掉线... - 5 - 4、默认号码及说明... - 5 - 5、配置文件说明... - 6 - 6、添加一个新的SIP账号... - 6 - 7、freeswitch用作软电话... - 6 - 8、配置SIP网关拨打外部电话... - 7 - 9、从某一分机上呼出... - 7 - 10、呼入电话处理。... - 8 - 11、测试freeswitch视频会议... - 8 - 12、freeswitch中的语音识别... - 9 - 13、在 FreeSWITCH 中使用 google translate 进行文本语音转换.

List list=new ArrayList()怎么回事

一、首先明确:List是接口,ArrayList是它的实现类 以下两种方法都可以,但是不提倡第二种: List list=new ArrayList(); ArrayList list=new ArrayList(); 二、那么第一种方法有什么好处? 在设计模式中有对依赖倒置原则。程序要尽量依赖于抽象,不依赖于具体。 从Java语法上,这种方式是使用接口引用指向具体实现。 比如,你若希望用LinkedList的实现来替代ArrayList的话,只需改动一行即可,其他的所有的都不需要改动: List list=new LinkedList(); 这也是一种很好的设计模式.一个接口有多种实现,当你想换一种实现方式时,你需要做的改动很小. 面向接口编程提高程序宽展性,以后修改维护好些 声明一个接口的变量(接口的引用)可以指向一个实现类(实现该接口的类)的实例, 但是该接口的变量不能使用实现类中有,接口中没有的方法(实现类中没有重写的方法,自添加的方法) 详细解释: ArrayList不是继承List接口,是实现了List接口。 你写成ArrayList arrayList = newArrayList();这样不会有任何问题。 和List list = new ArrayList();相比这2个写是有区别的。arrayList是一个ArrayList对象,它可以使用ArrayList的所有方法。 List是接口,它是不可以被实例化的(接口是个抽象类),所以必须以它的实现类去实例化它。list对象虽然也是被实例化为ArrayList但是它实际是List对象,list只能使用ArrayList中已经实现了的List接口中的方法,ArrayList中那些自己的、没有在List接口定义的方法是不可以被访问到的。 我们说,用接口去做是有它的好处的,如果你把类型定义成ArrayList(也就是一个具体的实现类)那么你就只能接收这一种类型的数据了,如果你要是定义为List那么你不仅可以接收ArrayList的对象还可以接收LinkedList的对象,这样你的程序就灵活了。 文章参考 三、例子看一下 声明接口: public interface Animal { void say(); void listen(); } 实现类: public class Dog implements Animal { @Override public void say() { System.out.println("say"); } @Override public void listen() { System.out.println("listen"); } public void run(){ System.out.println("run"); } } 测试类:

java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11Graphi

现象:项目中使用的二维码图片无法展示,查看图片链接报错500 解决方法:修改Tomcat的 bin/catalina.sh,找到 "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \ -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \ -Djava.security.manager \ -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \ -Dcatalina.base="$CATALINA_BASE" \ -Dcatalina.home="$CATALINA_HOME" \ -Djava.io.tmpdir="$CATALINA_TMPDIR" \ 这样的代码,在末尾加上-Djava.awt.headless=true \ tomcat7总共有7处,修改后重启tomcat

【系统问题】华为服务器系统初始化及安装流程(技术支持,请勿转载)

华为服务器系统安装(Centos系统)指导 1:开机进入启动界面 2:下面是加载启动阶段,等待跳过 3:等待系统加载到如下界面,选择F12进入PxE 4:输入密码,然后点击ok进入系统,密码在服务其标签上 5:点击Start进行确认 6:点击计算机的Configuration Wizard(计算机配置向导),进行硬盘相关的配置工作 7:点击人工配置(Manual Configuration) 8:选择增加配置(Add Configuration) 9:选择Add To Array 将未配置的硬盘增加到Drive Groups 10:增加完成之后,选择Accept DG 11:然后点击Next 12:选择Add to SPAN,再点击Next 13:下拉选择RAID0作为Virtual Drives, 参数配置完成之后点击accept,然后依次选择next,Yes,Accept 14:依次选择Yes 15:选择快速初始化(Fast Initialize),然后选择Yes,之后重启系统,插入安装关盘 16:持续等待,直到进入了Centos7如下的安装页面,选择安装Install Centos 7进行安装 17:配置好相关时间软件选择主机和网络相关信息,然后点击安装 18:安装完成之后选择接受许可,进入安装完成页面

使用NSIS制作驱动安装包

win10环境安装驱动的发现: 1.会在C:\Windows\INF目录下的setupapi.dev.log文件中记录信息,包括安装命令,安装结果。 2.可以使用pnputil安装驱动。由于安装后的inf文件会放到C:\Windows\INF目录下以oem#.inf命名,所以安装时需要记录对应的inf文件名。这里采用了如下方法,该方法也是参考stackoverflow上一个网友的回复: (1)记录下安装驱动前已有的驱动列表:pnputil /enum-drivers > driverlist_before.txt (2)安装驱动:pnputil /add-driver *.inf /install (3)记录下安装驱动后已有的驱动列表:pnputil /enum-drivers > driverlist_after.txt (4)比较两个文件的改动过滤输出oem#.inf:fc driverlist_after.txt driverlist_before.txt | findstr /C:"oem" > diff.txt 文件内容大致如下: (5)使用NSIS的stack将新增的oem#.inf过滤出来输出到文件,脚本见文末。 (6)卸载时读取该文件,卸载相应的inf(脚本见文末):nsExec::ExecToLog '"$SYSDIR\PnPutil.exe" /delete-driver $driver1 /uninstall /force' 3.使用NSIS编写脚本时直接使用nsExec::ExecToLog "pnputil /enum-drivers > driverlist_after.txt"不能识别">",而写到脚本中,再通过nsExec::ExecToLog "createDiff.cmd"执行脚本则是可以的。 4.在64位系统中使用上述命令需要在${DisableX64FSRedirection}和${EnableX64FSRedirection}之间。 5.其实在命令行执行pnputil的安装命令后,返回的安装结果信息中会有对应的oem#.inf的信息,但使用nsExec::ExecToLog命令调用pnputil来安装驱动会输出到窗口,可以使用nsExec::ExecToStack命令,输出到堆栈,然后通过$1获得输出信息,对此信息处理,使上述步骤得以简化。 有关windows驱动程序的介绍可以参考官方文档:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/ 此番操作仅供参考毕竟对驱动这块不太懂,有什么问题欢迎一起探讨。有兴趣可以看事情经过,没兴趣的可以之间跳到文末撸代码。 ------------------------------------------事情经过-------------------------------------------------------- 最近一个朋友询问能否帮忙做个windows的安装包,他本来是使用installshield2009制作的,现在想换inno setup。经过了解,我发现inno setup 和 NSIS功能相似,没什么差别,而之前我使用NSIS分分钟就做好了,就回复说用NSIS试一下。 朋友发来使用installshield制作的输出目录截图如下: 本来以为直接把这个安装包里的文件全部使用NSIS打包一遍就OK了,然而仔细询问后才知道是要做一个驱动的安装包(如上图的inf文件)。 于是在网上查找windows下安装驱动的方法,有几种驱动安装的工具,介绍如下: 1.devcon.exe(windows设备控制台):在 Microsoft Windows 2000 和更高版本的 Windows 上运行,用于更改设备配置(包括更新驱动程序,从驱动程序存储区添加删除第三方驱动程序包)。详细介绍请参考官方文档:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/devtest/pnputil-command-syntax。 2.difxcmd:通过 difxapi.lib 里的 DriverPackageInstall 来安装驱动 3.dpinst:使用静默方式安装不了驱动,必须要有交互 UI。 4.PnPUtil:从驱动程序存储区( C:\Windows\System32\DriverStore\FileRepository )中删除驱动和预安装驱动。Windows Vista 和更高版本的 Windows 上支持 PnPUtil。 PnPUtil 不适用于 Windows XP,但可以使用驱动程序安装框架(DIFx)工具来创建和自定义驱动程序包的安装。只能删除 oem开头的驱动(通过该命令安装的驱动都会以oem开头,但一个驱动具体是oem?需要自己想办法获取)。

使用openMVG重建3D点云结构遇到double free or corruption问题解决方法记录

使用openMVG重建3D点云结构遇到double free or corruption问题 安装openMVG之后,使用过程中遇到报错double free or corruption。记录了一些可能造成该问题的原因及解决办法。 情况1 当命令行调用openMVG_main_IncrementalSfM时,提示错误 double free or corruption 造成原因:可能是在编译openMVG的过程中使用的ceres模块不是自带的导致后边会出现调用错误. 解决办法:注释掉目录 openMVG/src/CMakeLists.txt里边的第260行左右的find_package(Ceres QUIET HINTS ${CERES_DIR_HINTS})。之后在重新编译安装openMVG。 参考:参考github issues 情况2 double free or corruption 造成原因:错误 double free or corruption还有可能是eigen版本造成的,openMVG应该是需要3.2.xxx版本的 解决办法:查看eigen版本是否符合要求,安装符合要求的版本 情况3 cmake文件中正确链接openMVG库作为第三方库,也可能避免double free or corruption。 target_link_libraries(main ${OPENMVG_LIBRARIES}) 参考:cmake正确链接openMVG为第三方库

38、Android编写应用-使用布局编辑器Layout Editor构建界面

在布局编辑器中,您可以通过将界面元素拖动到可视化设计编辑器中(而不是手动编写布局 XML),快速构建布局。设计编辑器支持在不同的 Android 设备和版本上预览布局,并且您可以动态调整布局大小,以确保它能够很好地适应不同的屏幕尺寸。 使用 ConstraintLayout 构建布局时,布局编辑器的功能尤其强大。前者是一个布局管理器,与 Android 2.3(API 级别 9)及更高版本兼容。 本文简要介绍了布局编辑器。如需详细了解布局基础知识,请参阅布局。 布局编辑器简介 当您打开 XML 布局文件时,就会显示布局编辑器。 图 1. 布局编辑器 Palette:包含您可以拖到布局中的各种视图和视图组。Component Tree:显示布局中的组件层次结构。工具栏:点击这些按钮可在编辑器中配置布局外观及更改布局属性。设计编辑器:在 Design 视图和/或 Blueprint 视图中修改布局。Attributes:用于对所选视图的属性进行控制的控件。视图模式:采用 Code 、Design 或 Split 模式查看布局。Split 模式会同时显示 Code 和 Design 窗口。缩放和平移控件:控制编辑器内的预览大小和位置。 当您打开 XML 布局文件时,默认会打开设计编辑器,如图 1 所示。如需在文本编辑器中修改布局 XML,请点击窗口右上角的 Code 按钮。请注意,在 Code 视图中修改布局时,Palette、Component Tree 和 Attributes 窗口不可用。 提示:您只需按 Alt + Shift + Right/Left arrow(在 Mac 上按 Control + Shift + Right/Left arrow),即可在设计编辑器和文本编辑器之间切换。 更改预览外观 您可以使用设计编辑器顶行中的按钮在编辑器中配置布局的外观。 图 2. 布局编辑器工具栏中用于配置布局外观的按钮 可用的按钮(对应于图 2 中的各个数字)如下:

Python列表推导式if else及一些应用

两种形式的列表推导式 1. 只有if…版 模板: [item for item in data if condition] 示例: # 剔除data中的奇数 data = [1, 2, 3, 4, 5, 6, 7, 8, 9] test = [item for item in data if item % 2 == 0] print(test) # 结果 [2, 4, 6, 8] 此处if主要起条件判断作用,data数据中只有满足if条件的才会被留下,最后统一生成为一个数据列表 2. if…else… 版 模板: [exp1 if condition else exp2 for x in data] 示例: # 一行代码实现data中偶数位的元素加2 data = [1,2,3,4,5,6,7,8,9] test = [data[i]+2 if (i+1)%2 == 0 else data[i] for i in range(len(data))] print(test) # 结果 [1, 4, 3, 6, 5, 8, 7, 10, 9] 此处if…else…主要起赋值作用,当data中的数据满足if条件时将其做exp1处理,否则按照exp2处理,最后统一生成为一个数据列表

圣杯布局和双飞翼布局简解

1. 什么是圣杯布局和双飞翼布局? 圣杯布局和双飞翼布局是一样的,都是两边固定宽度,中间自适应的三栏布局,中间栏要放在文档流前面以优先渲染。不过两者实现方式上有些区别 圣杯布局 双飞翼布局 2.为什么要使用双飞翼布局和圣杯布局 都是为了解决两边顶宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。 3.原理及代码 圣杯布局:为了中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>圣杯布局</title> <style> .container { border: 1px solid yellow; padding: 0 300px; } .container div { float: left; position: relative; } /* 中间自适应 */ .main { width: 100%; height: 300px; background: #FFFF00; } /* 左 */ .left { height: 300px; width: 300px; background: darkcyan; margin-left: -100%; left: -300px; } /* 右 */ .right { height: 300px; width: 300px; background: #0000FF; margin-left: -300px; right: -300px; } </style> </head> <body> <!

vue实现(一)- 数据结构实现

vue原理解析(一) 最近对Vue的原理进行学习,并对其部分原理进行模拟。通过学习,我发现Vue在html的使用中,一共由三个部分组成:M - V - VM,和原始的MVC框架的不同,VUE把controller层转换成ViewModel-连接Model和View,“桥”。我在学习的过程中,模拟了VUE的构建结构,希望通过我的分析,可以让我们在后面对VUE源码的解析更加的通俗易懂。 vue代码结构分析 我们在HTML中引入框架,通过JS引入vue.js <script type="text/javascript" src="../assets/js/vue.js"></script> 在HTML页面代码中,我们使用Vue的API <div id="root"> <div> <div> <p>{{name}} - {{message}}</p> </div> </div> </div> 再在JS中,创建VUE实例 var outData={ name: 'hello', message: 'world’ } var app=new Vue({ el:'#root', data:outData, }) 实现了如下效果 vue结构模拟 在模拟过程中,我们不需要引入JS,html代码也是和原来一致的只需要通过自己手写的方法,来模拟其结构。我们可以发现在VUE中,我们原始创建的DOM被生成的DOM替换了 我们可以发现,在浏览器中输出节点的时候,我们在调用Vue之前的节点,被替换了,生成后的节点被加载在了页面上。因此,我们需要模拟这种替换的过程 html <div id="root"> <div> <div> <p>{{name}} - {{message}}</p> </div> </div> </div> js <script> // 打印root console.log(root) // 获取元素的dom const dom = document.querySelector( '#root' ) // 设置data let data = { name: 'hello', message: 'world' } //对存在的Dom进行替换 let complier = (template, data) => { // 用于替换{{}}中数据的正则 const ruleForSupport = /\{\{(.

【问题解决】mysql-[Warning] InnoDB: Table mysql/innodb_table_stats has length mismatch in the column name

【问题解决】[Warning] InnoDB: Table mysql/innodb_table_stats has length mismatch in the column name table_name. Please run mysql_upgrade 产生原因解决方法官网bug修改 产生原因 根据提示:是数据库innodb_table_stats 表中table_name一栏长度异常导致的。 解决方法 1:执行mysl更新 mysql_upgrade --host=‘127.0.0.1’ --port=3306 --user=‘root’ --password=“root” 2:重启数据库mysql service mysql restart 官网bug修改 mysql 官网Bug Fixed 地址:https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-23.html Bugs Fixed Important Change; Partitioning: After creating partitioned InnoDB tables with very long names, the table_name columns in the corresponding entries in the mysql.innodb_index_stats and mysql.innodb_table_stats system tables were truncated. To fix this issue, the length of the table_name column in each of these tables has been increased from 64 to 199 characters.

【行为识别】TSN/TRN/TSM/SlowFast/Non-local

前言 记录视频理解领域的几篇文章吧,由于每篇值得记录的东西不多,所以合在一起。 关于开源框架,有港中文多媒体实验室的MMAction。有设备的就尽量多跑跑模型吧 视频相对于静态图像多了时间维度。静态图像的分类、检测、分割做得相对完善了,视频方面的工作想有创新必须在时间这个维度上钻研。 注意 Action Recognition和Spatio-temporal Action Recognition(又称action localization)的区别。前者只需判断视频的类别,后者要在视频中确定动作从第几帧开始第几帧结束,并在出现的帧上确定包含动作的bounding box。本文介绍的是前者。 预备知识 时空卷积 文章标题:A Closer Look at Spatiotemporal Convolutions for Action Recognition 首先探讨一下几种形式的时空卷积。 f-R2D: 帧上的2D卷积。对每一帧图像做2D卷积,最后将结果融合起来。R2D:视频段上的2D卷积。将帧的维度并入输入通道。假设有l帧,则网络的输入为3lxhxw。3D卷积:输入c×l×h×w(输入通道×帧数×高×宽),卷积核大小 CxKxKxZ(输出通道x宽x高x处理帧数),假设步长都为1,则输出Cx(l-Z+1)x(h-K+1)x(h-K+1). 以上都暂不考虑batchsize这个维度。3D卷积是2D卷积在时间维度上的拓展。MC卷积: 3D卷积和2D卷积的混合。MC卷积假设对时间处理越早越好,所以在前面的层用3D卷积,在后面的层用2D卷积。rMC卷积:与MC卷积结构相反,其在后面层采用3D卷积。2+1D卷积:把3D卷积分解为连续的空间上的2D卷积和时间上的1D卷积。优点是增加非线性且更易优化(3D卷积难优化). 设原3D卷积核大小 KxKxZ,可拆成KxKx1(空间卷积)和1x1xZ(时间卷积) 模型 TSN 文章标题: Temporal Segment Networks: Towards Good Practices for Deep Action Recognition pytorch 实现: https://github.com/yjxiong/tsn-pytorch Motivation :1,连续的帧信息往往高度相关,所以对帧作密集采样是不必要的 2,之前的方法都要求输入视频为64~120帧,不能广泛地应用 网络结构 由上图所示,一个输入视频被分为 K 段(segment),一个片段(snippet,几帧图像叠加在一起)从它对应的段中随机采样得到。不同片段的类别得分融合,这是一个视频级的预测。然后对所有模式的预测融合产生最终的预测结果。 文中设置K=3,融合用的是平均函数,分类用的是softmax TRN 文章标题 Temporal Relational Reasoning in Videos 本文是对TSN最后融合方式做一个改进。TSN每个snippet独立地预测,而TRN在预测前先进行snippet间的特征融合。另外TRN的输入用的是不同帧数的snippet(different scale)。 下图的框架图一目了然,算法实现流程就是先均匀地采样出不同scale的Segment 来对应 2-frame, 3-frame, …, N-frame relation;然后对每个Segment里小片提取 Spatial feature,进行 MLP 的 temporal fusion,送进分类器;最后将不同scale的分类score叠加来作最后预测值。

windows10升级Android Studio3.2到最新3.6.3版本遇到的冲突问题

根据提示升级Android Studio3.2到最新的3.6时,遇到以下报错: 不选任何内容,直接按Proceed或Cancel,试了几次都不行,无法升级成功。 起初还以为是家里的网络不能访问外网导致的。 后来,全选了所有项目,再点击Proceed,可以升级成功。 点了Proceed后,又出现以下进度条: 运行完后,Android Studio自动重启,加载界面就是升级后的Android Studio 3.6.3版本。升级后Android 版本信息如下: 再根据提示,升级gradle版本即可。

STM32驱动SPI接口EEPROM,AT25010、AT25020、AT25040

一、源代码 void eeprom_init() { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12; // PB12 推挽 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_11|GPIO_Pin_12); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //PB13/14/15上拉 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平 SPI_InitStructure.

配置Beyond Compare 4作为git mergetool来解决git merge命令导致的文件冲突

文章目录 前言解决方案前提配置 Beyond Compare文件冲突及处理产生冲突解决冲突 工具配置的参数含义git configgit mergetool 思考总结 前言 使用 git merge 命令合并代码的时候可能会产生文件冲突,产生这种冲突的根本原因是文件的同一处同时被多次修改,这种同时修改常体现的不同分支上,当多个分支修改了同一处代码,再合并代码的时候就会产生冲突,因为 git 程序也不知道我们想要保留哪一份修改,这时就需要我们手动修改产生冲突的文件。 当冲突内容很少的时候我们可以打开文本编辑器,找到 >>>>>>>>>>>>、=========== 和 <<<<<<<<<<<< 这三行字符包裹的内容就是需要解决冲突的部分,但是当冲突内容特别多时我们还是习惯于通过可视化的工具来处理,Beyond Compare 就是这样一款工具,可以用来比较不同的文本文件、表格文件,还可以比较文件夹内容,之前用着比较习惯,所以在处理 git 冲突的时候也想使用这个工具来做,通过查找技术文档发现了下面的方法。 解决方案 鉴于大家都比较急,查找问题时想要直接找到答案,所以我这里直接说明配置步骤,送给不求甚解的小伙伴,也方便今后我可以直接找到,不过配置之前还是要先看一下前提。 前提 在 Windows 上安装了 git 客户端,可以执行 git 命令(废话!没装 git 怎么产生冲突的)安装了 Beyond Compare 4 这个软件,下载链接很多,自己找一个吧,实在找不到,那就放弃吧(找我要) 配置 首先找到 Beyond Compare 的安装路径,比如我的软件安装路径是 D:\mybc4\BComp.exe,然后在 git 命令行客户端中执行下面命令: git config --global merge.tool bc4 git config --global mergetool.bc4.cmd "\"D:\\mybc4\\BComp.exe\" \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\"" git config --global mergetool.bc4.trustExitCode true git config --global mergetool.

使用vscode开发ns3项目(代码高亮、自动补全支持)

需求 需要复现一篇网络体系结构相关的论文。论文使用了ns3模拟,因此需要实现相应的ns3代码。 相关工具和前期准备 ns3模拟框架:ns3是进行网络模拟最常用的模拟框架。其在2008年发布了第一个版本,之后以每年2-3个版本的速度一直更新到现在,最新的版本是2019年的ns3-3.30。其最新的版本主要支持C++开发,大多数功能也提供了python接口。不过其只支持Linux系统。 ns3官网vscode、ubuntu、vmware:比较常见,此处不再介绍,如有需要可查阅官网和其他相关博客。本文将从已经安装好vmware(作者使用版本为VmWare 15 Pro,具体版本为15.5.2),ubuntu(作者使用版本为Ubuntu 18.04.01),ns3(作者使用版本为ns3-3.30.1),vscode(作者使用版本为1.45.1)的前提条件下继续。注意ns3和vscode都是安装在vmware中的ubuntu虚拟机上。 问题 在ns-3-tutorial中,ns3的开发者极尽详至的为我们介绍了ns3的用法。然而,在开发者看来,具体的IDE不应该出现在对ns3的介绍中,所以在tutorial中开发者一直使用在终端中输入命令./waf和./war --run的方式来编译和运行项目,对于代码文件的更改也只是称“使用你喜欢的IDE将代码修改为”。虽然说理论上我们可以通过vim和终端命令完成所需要的所有代码编辑功能,但是作为2020年的程序员,我们希望有IDE。 CodeBlock是很多Linux程序员喜欢的IDE,然而在我花了半个小时仍没有找到如何直接打开一个文件夹的功能后,我放弃了它。eclipse的C++支持也是一个非常经典的IDE,ns3的官网wiki上也有相关配置的介绍https://www.nsnam.org/wiki/HOWTO_configure_Eclipse_with_ns-3,但是当我看到那超过二十步的繁琐配置时,我失去了尝试这种方法的动力。除此之外,eclipse已经是十年前热门的IDE了,人总是喜欢用新一些的东西。关于ns3在windows和visual studio的支持,我也找到了官方wiki——https://www.nsnam.org/wiki/Ns-3_on_Visual_Studio,发现这是一项还在进行中的工作,而且现在还在四个阶段中的第一个阶段。其实我并不排斥使用终端命令去进行编译和运行,我最迫切需要的只是代码高亮和自动补全。 简单的需求一般都会有简单的方法去实现,这次也不例外。 解决方法 在youtube上找到了使用vscode进行配置,从而编写ns3程序的教程,链接如下。 ns3 Network Simulator - Configuring Visual Studio Code for Auto-Completion & Syntax Highlighting 该视频解决了我的所有需求。 大致步骤为: 安装vscode,安装C/C++扩展。进入相关目录,通过code .命令(注意那个".")使用vscode打开当前目录。按下ctrl+shift+c,在弹出菜单中找到相关设置进入设置。 按照视频教程中所述进行修改。 此处和视频中略有不同,视频中的includePath有两个值,作者称只使用第一个值(即上面图片中的值)的效果令他不是很满意。但是第二个值似乎跟ns3对eclipse的扩展有关。我在尝试了一下只使用一个值的效果后感觉已经很不错,因此便没有再去钻研第二个值的具体含义及效果。之后编辑代码,就会有类似于使用visual studio写C系代码的顺滑体验。当然现在的编译运行还是需要在命令行中输入命令。 结果 见视频。此处略。 其他 ns3其实感觉在设计上还有些可以完善的地方,比如有很多地方要使用set(属性名字符串,值字符串)的方法设置一些属性,是否可以将不同的属性字符串直接变为方法呢?这样就可以更好的使用IDE的自动补全功能。 另外,通过ns3,我偶然间发现了Google Summer of Code项目。可惜发现时已经截止报名了。但是看介绍时我感觉真的应该参加一次,我觉得它将会是一个难忘的经历。因此我在这里放一下网址,如果读者有兴趣可以了解一下。https://summerofcode.withgoogle.com/

nestedScrollView滑动监听

nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { @Override public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { if (scrollY > oldScrollY) { Log.e("=====", "下滑"); } if (scrollY < oldScrollY) { Log.e("=====", "上滑"); } if (scrollY == 0) { Log.e("=====", "滑倒顶部"); } if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) { Log.e("=====", "滑倒底部"); } } });

mysql中innodb和myisam对比及索引原理区别

mysql中innodb和myisam对比及索引原理区别 InnoDB和MyISAM是很多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,5.7之后就不一样了 1、事务和外键 InnoDB具有事务,支持4个事务隔离级别,回滚,崩溃修复能力和多版本并发的事务安全,包括ACID。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能 MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择 2、全文索引 Innodb不支持全文索引,如果一定要用的话,最好使用sphinx等搜索引擎。myisam对中文支持的不是很好 不过新版本的Innodb已经支持了 3、锁 mysql支持三种锁定级别,行级、页级、表级; MyISAM支持表级锁定,提供与 Oracle 类型一致的不加锁读取(non-locking read in SELECTs) InnoDB支持行级锁,InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,注意间隙锁的影响 例如update table set num=1 where name like “%aaa%” 4、存储 MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型, .frm文件存储表定义,数据文件的扩展名为.MYD, 索引文件的扩展名是.MYI InnoDB,基于磁盘的资源是InnoDB表空间数据文件和它的日志文件,InnoDB 表的大小只受限于操作系统文件的大小 注意:MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦 5、索引 InnoDB(索引组织表)使用的聚簇索引、索引就是数据,顺序存储,因此能缓存索引,也能缓存数据 MyISAM(堆组织表)使用的是非聚簇索引、索引和文件分开,随机存储,只能缓存索引 6、并发 MyISAM读写互相阻塞:不仅会在写入的时候阻塞读取,MyISAM还会在读取的时候阻塞写入,但读本身并不会阻塞另外的读 InnoDB 读写阻塞与事务隔离级别相关 7、场景选择 MyISAM 不需要事务支持(不支持)并发相对较低(锁定机制问题)数据修改相对较少(阻塞问题),以读为主数据一致性要求不是非常高 尽量索引(缓存机制)调整读写优先级,根据实际需求确保重要操作更优先启用延迟插入改善大批量写入性能尽量顺序操作让insert数据都写入到尾部,减少阻塞分解大的操作,降低单个操作的阻塞时间降低并发数,某些高并发场景通过应用来进行排队机制对于相对静态的数据,充分利用Query Cache可以极大的提高访问效率MyISAM的Count只有在全表扫描的时候特别高效,带有其他条件的count都需要进行实际的数据访问 InnoDB 需要事务支持(具有较好的事务特性)行级锁定对高并发有很好的适应能力,但需要确保查询是通过索引完成数据更新较为频繁的场景数据一致性要求较高硬件设备内存较大,可以利用InnoDB较好的缓存能力来提高内存利用率,尽可能减少磁盘 IO 主键尽可能小,避免给Secondary index带来过大的空间负担避免全表扫描,因为会使用表锁尽可能缓存所有的索引和数据,提高响应速度在大批量小插入的时候,尽量自己控制事务而不要使用autocommit自动提交合理设置innodb_flush_log_at_trx_commit参数值,不要过度追求安全性避免主键更新,因为这会带来大量的数据移动 8、其它细节 1)InnoDB 中不保存表的具体行数,注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的 2)对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引, 如果你为一个表指定AUTO_INCREMENT列,在数据词典里的InnoDB表句柄包含一个名为自动增长计数器的计数器,它被用在为该列赋新值。自动增长计数器仅被存储在主内存中,而不是存在磁盘 3)DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除 4)LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用 5)如果执行大量的SELECT,MyISAM是更好的选择,如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表 7、为什么MyISAM会比Innodb 的查询速度快 InnoDB 在做SELECT的时候,要维护的东西比MYISAM引擎多很多; 1)InnoDB 要缓存数据和索引,MyISAM只缓存索引块,这中间还有换进换出的减少

2D基本图形的Sign Distance Function (SDF)详解(下)

符号距离函数(sign distancefunction),简称SDF,又可以称为定向距离函数(oriented distance function),在空间中的一个有限区域上确定一个点到区域边界的距离并同时对距离的符号进行定义:点在区域边界内部为正,外部为负,位于边界上时为0。 您可以在 2D基本图形的Sign Distance Function (SDF)详解(上)这篇文章里找到前1~9个基础2D几何图形的SDF~ 10. 正五边形 代码: /** * 正五边形 1. 原点在中心点, 中心点到某一个顶点的向量沿y轴负半轴 * 2. r表示中心点到边的距离(不是到顶点的距离) */ float sdPentagon( in vec2 p, in float r ) { // pi/5: cos, sin, tan, !!!注意,k仅作为一个数据的集合! const vec3 k = vec3(0.809016994,0.587785252,0.726542528); p.x = abs(p.x); // 左右对称 // 1. 先映射:同样是分为三部分,上部+右上+右下,都要映射到上部 // 将op在(-k.x, k.y)上投影,得到一个系数,若系数是正数说明p点在上部不用处理,被min(0.0, )滤去 // 若为负数说明在目标范围内,p加上1倍的系数*单位垂直向量就可以到达对称轴处 // 再加一倍就到达对称点处,因此下面要乘2,-=其实和上面说到的垂直向量的方向有关 p -= 2.0*min(dot(vec2(-k.x,k.y),p),0.0)*vec2(-k.x,k.y); // 原先在右下部的区域,还得再映射一次,这里的min再滤去上部的部分 p -= 2.0*min(dot(vec2( k.x,k.y),p),0.0)*vec2( k.x,k.y); // 2.

YOLOv4训练自己的数据集

YOLOv4训练自己的数据集----记录 点击YOLOv4论文地址 本文基于代码链接实现训练自己的数据集 环境配置 Ubuntu+cuda10.02+python 1.下载模型文件 git clone https://github.com/AlexeyAB/darknet.git 2.下载预训练模型 链接:https://pan.baidu.com/s/1uJhsMlOvPfoIaipwYLKJIg 提取码:aiqt 将下载的yolov4.conv.137和yolov4.weights模型放在darknet目录中即可。 3.编译 如果需要使用GPU加速,那么得打开项目里面的Makefile文件修改一些参数的值。修改完成之后在直接make。 GPU=1 CUDNN=1 CUDNN_HALF=1 OPENMP=1 LIBSO=1 DEBUG=1 NVCC=/usr/local/cuda-10.2/bin/nvcc # 自己cuda安装位置 ##修改完成后 # cd 到 darknet-master 目录下 make 或者 make -j8 测试 # 测试图片,结果保存在 darknet-master/predictions.jpg ./darknet detect cfg/yolov4.cfg yolov4.weights data/dog.jpg # 如果内存不够,修改 cfg/yolov4.cfg batch=1 subdivisions=1 width=416 height=416 result 训练 1.准备自己的数据集,以voc数据集的格式存放 数据据制作过程参考:制作符合VOC格式的数据集 最后制作完效果如下: 按照上面格式准备好数据 Annotations是存放图片对应的标签xml文件 JPEGImage 存放图片 ImageSets --> Main -->test.txt train.txt trainval.txt val.txt 里面txt按行随机存放图片名字 如 000001 000002 000003… 2.

【VoLTE】增强型4GLTE开关默认处于关闭状态如何实现

[DESCRIPTION] MTK默认的版本中,Setting里面的增强4GLTE开关(VoLTE)默认是开启的,根据运营商的定制需求,想要将其默认设置为关闭状态 [SOLUTION] (1) package com.android.providers.settings; DatabaseHelper.java loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED, ImsConfig.FeatureValueConstants.ON);(两处地方),将ImsConfig.FeatureValueConstants.ON 改为 OFF (2) alps/device/mediatek/common/device.mk 文件中如下位置 ifeq ($(strip $(MTK_VOLTE_SUPPORT)), yes) PRODUCT_PROPERTY_OVERRIDES += ro.mtk_volte_support=1 PRODUCT_PROPERTY_OVERRIDES += persist.mtk.volte.enable=1 endif 将persist.mtk.volte.enable=1 修改为 :persist.mtk.volte.enable=0

Windows 10 家庭版 安装 docker for Windows( docker desktop) 详细步骤

以下步骤 比较详细的介绍了 自己在安装docker for Windows 的过程笔记,集百家之所长,可能遇到的一些,问题,但基本是只知其一不知其二,需要各位看官自己研究了,与君共勉。 注意注意!!!!! 说在最前面win10 家庭版 如果你想使用docker for Windows ,是需要开启Hyper-V 虚拟机的,但是,如果打开Hyper-V 功能的话,如果你安装了VM,那么你的 VM 虚拟机启动的时候,会报错冲突,需要你禁用关闭 Hyper-V。禁用关闭Hyper-V 的方式 在文章的第二部分 会有介绍 不想麻烦的话,家庭版可以安装 Docker Toolbox,因为 这个是基于 VirualBox 使用的。 win10 家庭版 安装 Hyper-V 要慎重 慎重 在慎重 下面的步骤介绍是不适用 docker toolbox 来安装 docker 的 一、安装docker for Windows (docker desktop) 的步骤 1、进入docker 官网 下载 docker desktop 2、下载完成之后 如果直接进行安装的话,如果出现以下安装提示: 出现错误“Docker Desktop requires Windows 10 Pro or Enterprise version 14393 to run.” 原因:win10必须为教育版或专业版,家庭版本的是不支持的,可以参考下 docerdoc 文档 3、家庭版安装的话,需要 管理员权限 【CMD】 执行一下 下面的指令:解决办法:伪装成专业版系统,通过 Docker 的系统检测

Python 提取指定中间字符串 取出字符串中间文本,利用正则表达式

由于业务需要,要提取指定字符串的关键信息。具体要求是从一个字符串中提取<>里面的内容。 于是想到利用Python 中的正则实现。 输入: 我要听<梁博>的<男孩> 输出: 梁博 男孩 Python 实现: #coding:utf8 import re import sys reload(sys) sys.setdefaultencoding('utf8') template = "我要听<歌手名>的<歌曲名>" def subString(template): rule = r'<(.*?)>' # 正则规则 slotList = re.findall(rule, template) return slotList slotList = subString(template) for slot in slotList: print slot

MFS分布式-master&chunkserver&client安装及使用

什么是分布式: 分布式文件系统就是把分散在多个计算机上的共享文件夹集合到一个共享文件夹,在用户要访问这些文件夹的时候 什么是MFS Moosefs是一个具有容错性的网络分布式文件系统,他把数据分散存在多个物理服务器上,而呈现给客户的是一个统一的资源 独有特征: 1.高可靠,数据的多个拷贝被存储在不同的计算机上 2.通过附加新的计算机或硬盘实现容量的动态扩展 3.删除的文件可以根据配置的时间周期进行保留 4.不受访问和写入影响的文件连贯快照 MFS的组成 元数据服务器(master):在整个系统中负责管理文件系统,维护元数据,目前不支持高可用 元数据日志服务器(metalogger):备份master服务器的变化日志文件,当master服务器损坏,可以从日志服务器中取得文件恢复 数据存储服务器(chunk server):真正存储数据的服务 客户端(client):可以像挂载NFS一样 挂载MFS文件系统 一. 安装元数据服务器(Master) master需安装以下4个RPM软件包 安装完后会生成一个mfs的用户,后续数据服务器,客户端都需要和它保持一致 需要更改解析: 启动服务: 二.安装chunk server服务器2台 找包安装: 更改mfs的uid gid 需要和masterd的mfs保持一致 解析: vim /etc/hosts 每台都要做 建立目录并更改用户和组: 更改配置文件: 启动: 测试: 三.客户端安装 测试: 关闭一台chunkserver结果: 四.存储类.标签 在chunkserver打标签: 所打标签: 给目录dir1打标签: mfsscadmin creat 2A class 2A mfssetclass -r class2A dir1 五.数据删除恢复 一条自己也不太懂,但是master关闭后输入后,启动就OK了的

xml的cdata

术语CDATA指字符数据。CDATA定义为文本块,但识别为标记. 预定义实体的同位素;,密度,并且与放大器;需要打字并且通常难以阅读的标记。在这种情况下,CDATA部分都可以使用。通过使用CDATA节,你是指挥,该文件的具体内容没有标记,并应被视为普通的文本解析器. 句法 以下是句法的CDATA节: ? 1 2 3 <![CDATA[ characters with markup ]]> 上述的语法是由三个部分组成: CDATA节启动 - CDATA开始于9个字符分隔符 <![CDATA[ CDATA节结束 - CDATA节用 ]]> 分隔符结束. CDATA节 - 这两个机箱之间的字符被解释为字符,而不是作为标记。这部分可以含有标记字符(<,>,和&),但它们是由XML处理器忽略. 示例 下面的标记代码显示例如CDATA的。在这里,写在CDATA节内的每一个字符由解析器忽略. ? 1 2 3 4 5 < script > <![CDATA[ < message > Welcome to YiiBai </ message > ]] > </ script > 在上面的语法中,<信息>和之间的所有内容将被视为字符数据,而不是作为标记. CDATA规则 这种规则需要遵循为XMLCDATA: CDATA不能包含字符串“]]>”的XML文档中的任何地方. 嵌套不允许在CDATA节.

用LSTM进行时间序列预测(单步,多步,单变量,多变量)

0. LSTM用于时间序列预测 LSTM因其具有记忆的功能,可以利用很长的序列信息来建立学习模型,所以用它来进行时间序列的预测会很有优势。 在实际工程中用LSTM进行时间序列的预测主要有两个难点:一是前期对数据的处理,二是初始模型的搭建。对数据的处理无论是单步、多步、单变量还是多变量都会用到滑动窗口来处理数据,具体处理的方法后面会进行阐述;而对模型的搭建则要根据要解决的问题,原始数据的情况等,对模型的参数做相应的设定,如果单纯的LSTM无法满足要求,一般会加入全连接层来解决。 1. 单变量单步 单变量单步的预测是最简单的,比如说有一组数据为: [1,2,3,4,5,6,7,8,9,10],然后要求利用这组数据训练一个模型,使其能对后面提供的数据做一个单步的预测。 我们先来对数据进行处理,处理的时候要根据不同框架所要求的LSTM的输入形式来处理,比如我们用Pytorch框架的时候输入要求是(seq_len, batch, input_size)。 因为是单变量的数据,我们令input_size=3,然后设seq_len=7,然后batch为1, 处理后的数据变为: [[1,2,3], =====> [4] [2,3,4], =====> [5] [3,4,5], =====> [6] [4,5,6], =====> [7] [5,6,7], =====> [8] [6,7,8], =====> [9] [7,8,9]] =====> [10] 前半部分是输入,箭头指向输出。也就是说将数据分批输入LSTM,没三个数据对应一个单步的预测目标。 数据处理好之后就是模型的搭建了,我们根据输入输出的形式来反推模型的结构。我们知道LSTM的结构是lstm = nn.LSTM(input_size, hidden_size, num_layers),由上面给出的输入的形式可以确定input_size=3, hidden_size, num_layers这两个参数要自己设置,也就是隐藏层的大小和层数。我们的预计输出的形式为(7,1),但是LSTM的标准输出形式为: output=(seq_len,batch,num_directionshidden_size)=(7,1,num_directionshidden_size), 当num_directionshidden_size不为1时我们需要在LSTM的后面加一个全连接层,并令全连接层的输入形式为num_directionshidden_size,输出为1 。这样我们的输出就变为了output=(7,1,1) ,然后用reshape方法(当out为numpy array时)或者view方法(当out为tensor时)将output整形为(7,1)。这样就可以用在后面的训练中了,即计算损失函数和反向传播。 2. 多变量多步 比如一组数据为: [[1,11],[2,12],[3,13],[4,14],[5,15],[6,16],[7,17],[8,18],[9,19],[10,20]] 要求对其进行两步预测,则我们对其进行处理: [[[1,11],[2,12],[3,13]], ======>[[4,14],[5,15]] [[2,12],[3,13],[4,14]], ======>[[5,15],[6,16]] [[3,13],[4,14],[5,15]], ======>[[6,16],[7,17]] [[4,14],[5,15],[6,16]], ======>[[7,17],[8,18]] [[5,15],[6,16],[7,17]], ======>[[8,18],[9,19]] [[6,16],[7,17],[8,18]], ======>[[9,19],[10,20]] 前半部分是输入,箭头指向输出。seq_len=6,batch=3,input_size=2 搭建模型的部分跟上面的分析是一样的,output的形状跟target一样为(6,2,2),而输入的形状为(6,3,2),所以还是需要一个全连接层使其输入为(6,3,2)输出为(6,2,2),这样才能用在后面的训练中。 最后如果要画出输出的图像的话可以取out[:3, 0, :]和out[:,1,:]在axis=0上拼接出来。

【Python】Tkinter教程

什么是Tkinter? Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。 由于 Tkinter 是内置到 python 的安装包中、只要安装好 Python 之后就能 import Tkinter 库、而且 IDLE 也是用 Tkinter 编写而成、对于简单的图形界面 Tkinter 还是能应付自如。 使用 导入 import tkinter 注意:Python3.x 版本使用的库名为 tkinter,即首写字母 T 为小写。 创建一个GUI程序 1、导入 Tkinter 模块2、创建控件3、指定这个控件的 master, 即这个控件属于哪一个4、告诉 GM(geometry manager) 有一个控件产生了。 #!/usr/bin/python3 import tkinter top = tkinter.Tk() # 进入消息循环 top.mainloop() 窗口主体框架 每一个 tkinter 应用的主体框架都可以包含下面这部分. 定义 window 窗口 和 window的一些属性, 然后书写窗口内容, 最后执行window.mainloop让窗口活起来. import tkinter as tk window = tk.

双线性插值法之放大收缩图像及其python实现

一维线性插值 假设我们已知坐标(x0,y0)与(x1,y1),要得到[x0,x1]区间内某一位置x在直线上的值。根据图中所示可得: 通过斜率比,可以得到下面的等式。 双线性插值 如图所示:所谓双线性插值,也就是连续使用三次一维线性插值,最终求得g(u0,v0)。 第一次:由g(u’,v’)和g(u’+1,v’)一维线性插值求g(u0,v’). 第二次:由g(u’,v’+1)和g(u’+1,v’+1)一维线性插值求g(u0,v’+1). 第三次:由g(u0,v’)和g(u0,v’+1)一维线性插值求g(u0,v0). 如何用双线性插值放大或收缩图像 我们只需要做两件事: 计算新图像像素在原图像的对应位置通过位置,在原图像找到4个点来计算新图像对应位置的像素 f(x,y)表示输出图像,g(u,v)表示输入图像。图像放大或缩小的几何运算可定义为: f ( x , y ) = g ( u 0 , v 0 ) = g [ a ( x , y ) , b ( x , y ) ] f(x,y)=g(u_0,v_0)=g[a(x,y),b(x,y)] f(x,y)=g(u0​,v0​)=g[a(x,y),b(x,y)].如果令 u 0 = a ( x , y ) = x c , v 0 = b ( x , y ) = y d u_0=a(x,y)=\frac{x}{c},v_0=b(x,y)=\frac{y}{d} u0​=a(x,y)=cx​,v0​=b(x,y)=dy​.

部署etcd集群

参考: https://www.cnblogs.com/51wansheng/p/10234036.html 一、环境说明 ubuntu 18.04 172.18.0.30 (master)ubuntu 18.04 172.18.0.26 (node1)etcd 版本:v2.3.7 二、安装etcd 分别在master和node1机器上安装etcd # step1:下载某版本etcd的release包 $ wget https://github.com/etcd-io/etcd/releases/download/v2.3.7/etcd-v2.3.7-linux-amd64.tar.gz # step2:解压安装到 /data/ 目录下(安装到那个目录可以自己定) $ tar -C /data -zxvf etcd-v2.3.7-linux-amd64.tar.gz # step3:检查安装是否成功 $ /data/etcd-v2.3.7-linux-amd64/etcdctl -v etcdctl version 2.3.7 三、配置etcd etcd重要配置参数的说明,不通版本的etcd可能参数选项以及选项的默认值会有些许出入,可以通过 etcd --help查看 --name # etcd实例名称 --data-dir # etcd数据存储的目录 --listen-client-urls # 供外部客户端使用的url --advertise-client-urls # 广播给外部客户端使用的url --listen-peer-urls # 集群内部通信使用的url --initial-advertise-peer-urls # 广播给集群内其他成员访问的url --initial-cluster # 初始集群成员列表 --initial-cluster-token # 集群的名称 --initial-cluster-state # 初始集群状态,new为新建集群(master为new,node为existing) 我们通过systemd来管理etcd服务,所以在/etc/systemd/system目录下新建etcd.service文件,不了解systemd的可以查看阮一峰老师的博客 1、master机器(172.18.0.30) # vim /etcsystemd/system/etcd.

ExecutorService的submit方法使用过程中的坑和源码剖析

最近在项目中集成了LeakCanry 来检测项目中出现内存泄漏,结果发现了EventBus 导致的内存的泄漏,然后引出了ExecitorService 的submit方法会catch掉所有的异常的问题(包含运行时异常)。 1, Java中的异常之RuntimeException 下面的链接是关于Runtime Exception 的描述: https://www.tutorialspoint.com/how-to-handle-the-runtime-exception-in-java 1.1 运行时异常的概念 运行时异常是Java编程语言的所有的异常的父类;当运行时异常 发生的时候,程序或者应用应该崩溃。跟其他的不是运行时异常不同,运行时异常永远不会被检查。 运行时异常通常显示程序员的错误,而不是程序处理的条件。当一个条件不能发生的时候,运行时的异常也会被使用到。应该注意的是:当让一个程序的内存用完了,一个程序的错误会被抛出而不是显示运行时异常。 1.2 常见的运行时异常 下面是常见的运行时异常: NullPointerException ArrayIndexOutOfBoundsException InvalidArgumentException IllegalArgumentExeception 1.3 使用ExecutorService 的submit 方法之后导致,运行时的异常被catch 的问题 下面的截图是: 上面LeakCanry 扫描应用得到了关于EventBus没有解注册而导致了内存的泄漏,正常的代码的逻辑肯定是有解绑的操作。现在出现的问题就是为什么下面的解绑的操作没有被调用到: EventBus.getDefault().unregister(object); 这段代码是在ExecutorService 的submit方法里面调用的,通过推理,我们很容易得到,在这个方法里面在EventBus 解绑之前可能抛出了运行时的异常,从而导致在抛出异常之后的代码未被执行。下面的截图果然验证我的猜想: 结果应用层抛出了IllegalArgumentExeception.那么现在的问题来了,在运行时异常的概念里面我们知道,发生了运行时的异常时,应该程序应该会崩溃才对,为什么这里发生了运行时异常,程序没有崩溃?研究了ExecutorService的源码之后,这个疑问就得到解决了。 2,ExecutorService 方法的源码剖析 首先我们使用Navigate工具栏的Type Hierarchy 工具查看ExecutorService 的继承的关系: ExecutorService 的submit 方法最后调用的是AbstractExecutorService 的submit方法: newTaskFor方法返回的是一个FutureTask 对象。 FutureTask被执行的时候,调用的是FutureTask 的run 方法,如下图所示 结果里面的异常被setExecption 方法吸收掉了,并没有抛出来。所以出现了上面的问题。即IllegalArgumentExeception被ExecutorService 的submit方法Catch了。 3,总结 使用ExecutorService 的时候尽量优先使用execute方法替代submit 方法,避免submit方法try catch 掉运行时异常,从而导致内存泄漏等等问题。ExecuteService 使用了execute方法之后,应用就会崩溃,出现下面的界面,我们只需要解决代码的错误即可解决。 后记:最近看了刘未鹏的《暗时间》一书,就下定决定自己加入写博客的行列。书中有一句话说的很好:“写是更好的一种思考的方式。”我们常常把思考挂在嘴边,却从未去反思自己:何为思考?何为更好的思考方式。读了《暗时间》之后我找到了答案:用心写作,至少坚持8年。我想8年之后我再回头看看自己曾写过的文章,会不会有点感悟?当然时间会告诉我答案。用我喜欢的苏东坡的一首诗里面的一句话:“人生到处知何似,应是飞鸿踏雪泥。泥上偶然留指爪,鸿飞那复计东西。”希望在以后的岁月回顾起曾经的自己,像飞鸿在泥上留下指爪一样,给自己留一些东可以思量和回忆的东西。

Centos screen的安装与使用

一、screen命令是什么? Screen是一个可以在多个进程之间多路复用一个物理终端的全屏窗口管理器。Screen中有会话的概念,用户可以在一个screen会话中创建多个screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。 二、如何安装screen命令? CentOS系统可以执行:yum install screen ; 三、screen命令使用方法? 3.1 创建screen会话 可以先执行:screen -S lnmp ,screen就会创建一个名字为lnmp的会话。 3.2 暂时离开,保留screen会话中的任务或程序 当需要临时离开时(会话中的程序不会关闭,仍在运行)可以用快捷键Ctrl+a d(即按住Ctrl,依次再按a,d) 3.3 恢复screen会话 当回来时可以再执行执行:screen -r lnmp 即可恢复到离开前创建的lnmp会话的工作界面。如果忘记了,或者当时没有指定会话名,可以执行:screen -ls screen会列出当前存在的会话列表,如下图: 11791.lnmp即为刚才的screen创建的lnmp会话,目前已经暂时退出了lnmp会话,所以状态为Detached,当使用screen -r lnmp后状态就会变为Attached,11791是这个screen的会话的进程ID,恢复会话时也可以使用:screen -r 11791 3.4 关闭screen的会话 执行:exit ,会提示:[screen is terminating],表示已经成功退出screen会话。VPS侦探 https://www.vpser.net/ 3.5 远程演示 首先演示者先在服务器上执行 screen -S test 创建一个screen会话,观众可以链接到远程服务器上执行screen -x test 观众屏幕上就会出现和演示者同步。 3.6常用快捷键 Ctrl+a c :在当前screen会话中创建窗口 Ctrl+a w :窗口列表 Ctrl+a n :下一个窗口 Ctrl+a p :上一个窗口 Ctrl+a 0-9 :在第0个窗口和第9个窗口之间切换

lotus v26 存储32GB扇区时间

lotus v26 存储32GB扇区时间 1,存储一个32GB扇区 1,存储一个32GB扇区 cpu和显卡 AMD Ryzen 9 3950X 16-Core Processor GeForce GTX 1080 Ti mem:125Gi swap:105Gi 存储一个32GB扇区 7h27分钟 2020-05-19T09:20:08.328+0800 INFO sectors storage-fsm@v0.0.0-20200427182014-01487d5ad3c8/states.go:70 performing sector replication... {"sector": "0"} 2020-05-19T16:47:20.137+0800 INFO sectors storage-fsm@v0.0.0-20200427182014-01487d5ad3c8/fsm.go:190 Proving sector 0 seal_pre_commit_phase1 4h43m 2020-05-19T09:20:13.677 INFO filcrypto::proofs::api > seal_pre_commit_phase1: start 2020-05-19T14:03:32.180 INFO filcrypto::proofs::api > seal_pre_commit_phase1: finish seal_pre_commit_phase2 1h33m 2020-05-19T14:03:32.400 INFO filcrypto::proofs::api > seal_pre_commit_phase2: start 2020-05-19T15:36:29.540 INFO filcrypto::proofs::api > seal_pre_commit_phase2: finish snark_proof 1h2m 2020-05-19T15:44:53.202 INFO filecoin_proofs::api::seal > snark_proof:start 2020-05-19T16:46:30.

手把手教你EEG脑电数据预处理-原理篇

目录 0. EEG data1. 定位通道数据2. 删除无用数据3.滤波4.分段5.基线校正6. 重参考7. 降低采样率8. 插值坏导9. 独立主成分分析10. 剔除坏段 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区 .QQ交流群:941473018 感谢简书ID:亚内士多德 授权分享 EEG脑电数据预处理-原理篇 本文不涉及具体的操作步骤,而是对脑电数据预处理中的每一步进行解说,根据我自己的经验来解释为什么要这么做,希望能够对刚入门脑电数据的朋友有所帮助。如果发现有什么错漏之处,也请指正。 基本步骤 定位通道位置 删除无用通道 滤波 分段 基线校正 重参考 降低采样率 插值坏导 独立主成分分析 剔除坏段 0. EEG data 首先要认识脑电数据是什么样子。我们采集到的原始信号,是一系列随着时间变化而不断变化的曲线,如下图所示,这是一个8个通道的示例数据,一共有两种mark类型,分别为S1跟S2。 mark,或者event,或者trigger,其实表示的都是同一个意思,即在我们关注的事件发生时,打上一个我们认得出的标记,这样子就可以从我们收集到的一长段数据中,找到我们感兴趣的事件范围了。 EEG示例数据 1. 定位通道数据 首先我们将EEG数据加载进eeglab之后,eeglab能够读取到的仅仅是每一个通道的名称和数值,但是它并不知道这个通道是位于头皮上的什么地方,因此我们需要加载进一个跟记录数据时相匹配的通道位置信息 eeglab中默认的文件是 standard-10-5-cap385,指的是按照国际10-5系统排布的一共有385个电极点信息的模板,一般来说使用这个模板就可以了。 关于模板的更多信息还可以看这里《脑电定位系统》、《10-20国际标准导联系统》 2. 删除无用数据 在采集数据的过程中,有可能会记录一些后期并不需要用到的通道信息,这时候我们就可以将它们剔除掉,不必纳入后续的分析中。 比如双侧乳突点。又比如眼电通道的数据。在使用eeglab来对数据进行预处理的时候,可以通过ICA的方式来去除眼电成分,而这种方式可以不需要眼电通道数据的参与就可以进行。 3.滤波 滤波分为高通滤波,低通滤波,带通滤波和凹陷滤波。 高通滤波是指,高于某个频率的信号可以通过,而低于这个频率的信号会被衰减过滤掉。而低通滤波则相反,指的是低于某个频率的信号可以通过,而高于这个频率的信号则相反。所以,在输入数值的时候,高通滤波要输入的是一个较小的数字,而低通滤波则是输入一个较大的数字。这可能跟我们的第一反应有点相悖。因此,也可以用它们的英文叫法来辨别,高通high-pass,低通low-pass,英文看起来就更为直观了。 而带通滤波,指的是在某个频率段范围内的信号可以通过,而这个频率段范围以外的信号会被衰减过滤掉,就相当于同时做了高通滤波和低通滤波。 凹陷滤波,指的是在某个频率范围内的信号会被衰减过滤掉,而这个频率范围以外的信号会被保留下来。这个操作通常是用来去除50Hz市电的干扰。我国的50Hz,因此在收集到的信号中,会有一个非常强烈的50Hz频段的信号存在,这就可以用凹陷滤波来去掉。 值得注意的是,滤波并不能完全过滤出我们想要的频段。比如30Hz的低通滤波,并不是说30Hz以外的信号就通通被过滤掉了,而是以30Hz为截止频率,高于这个截止频率的信号会被逐渐衰减。 如下图所示,横轴为频率,纵轴为增益系数,在截止频率f的左边,最开始的增益系数皆为1,指的是信号乘以1,被完整保留下来,而在接近截止频率的一定范围内,增益系数开始逐渐下降,直到我们的截止频率f处,增益系数正好是0.5,指的是经过了截止频率为f的低通滤波之后,f这个频段的数据有50%被过滤,而50%被保留下来。随后增益系数再逐渐下降,信号被逐渐衰减,直至接近于0。 因此,我们有时候会看到数据在做了30Hz的低通滤波之后,还会再做一个50Hz的凹陷滤波,就是因为,并不是做了30Hz的低通滤波就能够完全把30Hz以上的信号全部过滤掉,而50Hz的干扰又是非常强的,所以最好还是再做一个50Hz的凹陷滤波。 低通滤波器 4.分段 我们的数据是从实验开始到实验结束时全程记录的,但是我们感兴趣的,只是被试在接受到某个刺激,或者做出某个反应时那段事件的信号,因此,我们要根据我们打上的mark,讲数据切分成一段一段的,而在这些范围以外的数据,我们就不要了。 一般的ERP分段在事件前200毫秒到事件后1000毫秒这个时间段就足够了,因为几乎所有的ERP成分,都是在1秒以内产生的。但是如果后期还要做时频分析的话,则需要将分段时间拉长,扩大到事件前1秒到事件后2秒这个时间段内,因为时频分析的算法,要求数据要有一定的长度。 5.基线校正 在ERP实验中,我们关心的是这个刺激事件带给被试什么样的变化,因此需要有一个比较。而在事件发生之前的时间里,我们认为被试是处于一个相对平静的状态,此时的脑电活动,代表了一个平静状态下的脑电活动。所以我们将这段时间内的脑电活动当成一个基线,拿事件发生之后的活动去跟它做比较,来分辨刺激事件到底让被试产生了什么样的活动。 一般来说,都是以分段中,事件之前这段时间来作为基线的,比如分段为-200毫秒到1000毫秒,那就将所有的数据,减去前200毫米以内数据的均值。换言之,,就是将这前200毫秒以内的数据均值当成是“海平面”,所有其他的数据的数值,都是相对于这个“海平面”数据的高度。 基线校正的第二个作用,防止数据漂移带来的影响。有时候因为某些原因,我们采集到的数据,会呈现一个逐渐缓慢向上漂移的趋势,而在分完段之后,由于向上飘的影响,每一段数据的起点将不在同一个地方,也会使得这段数据的绝对波幅变高。而基线校正就可以校正这种漂移带来的影响,让每一段数据都拥有一个差不多的起点。 6. 重参考 首先要解释的是参考的定义。我们看到采集之后的数据是一个个的数值,但这个数值是什么意思呢,就是电极所在位置跟参考电极之间的电位差。 一般在脑电记录的时候会采用的参考电极有鼻尖参考,cz或头顶中央参考,还有单侧乳突参考,乳突就是耳朵后面一小块突起的区域。我们所看到的每个通道的数值,其实就是指这个通道跟参考通道之间的电位差。 在分析数据的时候,有时候我们会想要转换参考点的位置。因为不同位置的参考,会对数据造成一定的影响。比如记录时采用的是cz或头顶中央参考,那么自然地,距离cz点较近的电极点,记录到的电位差会非常小,而离得远的电极记录到的电位差就自然会大一点,这种大与小的差异,并不是由认知活动产生的,而是由记录方式产生的。又比如,单侧乳突参考,那脑袋左边的电极点跟右边的电极点,也会存在着记录方式不同产生的电位差不同。 常用的一些参考位置有双侧乳突平均参考,指将两个乳突数据的平均值作为参考数据,或者是全脑平均参考,指的是将全脑所有数据的均值作为参考数据的方法,不过使用全脑平均参考的时候要注意,眼电数据不要纳入其中,因为眼电数据的波动起伏非常大,很容易对数据造成比较大的干扰。 7. 降低采样率 采样率的单位是Hz,指的是一秒内要记录多少个数据点的意思,比如原始数据的采样率是1000Hz的话,就是代表一秒内有1000个数据点。

仿携程实现带价格的日历

参考文章:https://blog.csdn.net/BetterGG/article/details/80570183 日历在参考文献上进行了修改,使用JS+HTML+ES6/7,并对日历进行了进一步封装,使其使用更加方便,同时对样式进行了可配置化,用户可以通过自己的需求来修改需要的样式 实现效果如下: 属性 属性类型描述默认值elementDOM需要添加到的DOM元素falsebgColorString选中后的背景颜色#eb8300colorString选中的文字颜色#ffd101unClickTxtColorString不能选择的字体颜色#cccarrayJSONArray传递的数据[]delayInt延迟几天可以选择4headerBgColorString日期的背景色whiteweekendTxtColorString周六周日的文字颜色#ffd101workDayTxtColorString周一到周五的文字颜色blackindexInt展示几个月份的4bgCalenderString日历背景色whitecallbackFunction选中时的回调返回值:{date:“”,id:“”,price:“”} 简单使用 引入依赖 npm install dfh-calender 使用 <!-- * @Author: dfh * @Date: 2020-05-18 11:15:28 * @LastEditors: dfh * @LastEditTime: 2020-05-18 11:17:42 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="./node_modules/dfh-calender/css/common.css" /> <link rel="stylesheet" href="./node_modules/dfh-calender/css/calender.css" /> <style></style> </head> <body> <div class="calender"></div> </body> <script src="./node_modules/dfh-calender/lib/calender.js"></script> <script> var arrayJSON = [ { id: "0", date: "2020-04-29", price: "¥123" }, { id: "

自动生成自增协议号

自动生成自增协议号 生成规则代码展示 生成规则 生成规则为“AA+时间到天+四位数自增序列号”,如AA202005190001 代码展示 /** * 自动生成协议号 * 生成规则为“AA+时间到天+四位数自增序列号”,如SA202005190001 * @return */ private String generateAgreementCode(Long entId) { String agreementPrefix = "AA"; String currentLocalDateTime = LocalDateTimeUtil.getCurrentLocalDateTime("yyyyMMdd"); String code = serviceAgreementDao.selectLatestAgreementCode(entId); String agreementSuffix; if (code == null) { agreementSuffix = formatNumber(1L); } else { String substring = code.substring(code.length() - 4); agreementSuffix = formatNumber(Long.parseLong(substring) + 1); } return StringUtil.concat(agreementPrefix, currentLocalDateTime, agreementSuffix); } public String formatNumber(Long id) { NumberFormat numberFormat = NumberFormat.getInstance(); //设置是否使用分组 numberFormat.

Python实现数据预处理--特征标准化与归一化

本文不对标准化和归一化相关原理和公式作阐述 标准化(均值移除) 由于一个样本的不同特征值差异较大,不利于使用现有机器学习算法进行样本处理。均值移除可以让样本矩阵中的每一列的平均值为0,标准差为1。 转换公式如下: 标准化的意义: 想象一下,我们经常通过梯度下降来进行优化求解,公式一般如下,如果特征之间的数值差异太大,那么更新的结果肯定也会产生较大的差异,这是我们所不希望的。在最开始的时候,我们认为特征之间的重要程度的是一样,并不想偏袒哪个特征,所以这部预处理工作必做! import pandas as pd import numpy as np df = pd.read_csv( '../data/wine_data.csv', #葡萄酒数据集 header=None, #用哪行当做列名,我们自己来指定 usecols=[0,1,2] #返回一个子集,我们拿部分特征举例就可以了 ) df.columns=['Class label', 'Alcohol', 'Malic acid'] df.head() 在数据中,Alcohol和Malic acid 衡量的标准应该是不同的,特征之间数值差异较大 from sklearn import preprocessing std_scale = preprocessing.StandardScaler().fit(df[['Alcohol', 'Malic acid']]) df_std = std_scale.transform(df[['Alcohol', 'Malic acid']]) print('Mean after standardization:\nAlcohol={:.2f}, Malic acid={:.2f}' .format(df_std[:,0].mean(), df_std[:,1].mean())) print('\nStandard deviation after standardization:\nAlcohol={:.2f}, Malic acid={:.2f}' .format(df_std[:,0].std(), df_std[:,1].std())) #输出结果: Mean after standardization: Alcohol=-0.00, Malic acid=-0.00 Standard deviation after standardization: Alcohol=1.

curl: error while loading shared libraries: libcurl.so.4: cannot open shared

curl: error while loading shared libraries: libcurl.so.4: cannot open shared curl:加载共享库时出错:libcurl.so.4:无法打开共享 基于对ubuntu不是很了解,碰到问题也没有很好的解决方案 于是就自行baidu和Google,由于问题背景不同,出现的解决方案 也各有不同,不过按照网上说的没解决实际问题,基于以上问题, 有人说是没有安装curl,本人也通过curl -V 命令执行,确实发现 是没有安装过curl环境,后面根据网上的一些指示,去 https://curl.haxx.se/download.html 网站上下载了版本偏高的tar包,并上传服务器解压,依次执行 .configure make make install 命令,安装curl环境,再通过curl -V命令检验是否安装成功。 以上百度参考:https://blog.csdn.net/weixin_43938510/article/details/88143293 安装成功,满怀期待得执行mongod -f xxx 命令,结果又报另外一个错,具体错误如下: mongod:/usr/lib/libcurl.so.4: no version information available(required by mongod) 于是又在网上找到另外一种说法,安装的curl版本太多,不知道用哪个 locate libcurl.so.4 查看命令 以上百度参考: https://blog.csdn.net/jfkidear/article/details/91536953 最后折腾半天还是没有解决,实在不行后面在本机上面安装ubuntu,再把mongodb重新部署到本机 虚拟机上,也发生了同样的错误,后面又折腾了白天,解决了本地虚拟机上的问题, 具体解决方案: sudo apt-get update sudo apt-get -f install sudo apt-get install libcurl4-openssl-dev sudo apt-get install curl

python报错:float object is not callable

文章目录 如图报错出错代码解决办法 如图报错 出错代码 # -*- coding: utf-8 -*- """ @File : 梯度下降法求函数最小值.py @Time : 2020/5/17 21:30 @Author : Dontla @Email : sxana@qq.com @Software: PyCharm """ # 函数 def f(a, b): return a ** 2 + b ** 2 # 梯度 def gra_f2x(a, b): return 2 * a def gra_f2y(a, b): return 2 * b # 位移向量 def delta_x(gra_x, ita): return gra_x * ita def delta_y(gra_y, ita): return gra_y * ita if __name__ == '__main__': # 学习率 eta = 0.

python抓取谷歌指数(Google Trends)

过去7天的数据链接:https://trends.google.com/trends/api/widgetdata/multiline?hl=zh-CN&tz=-480&req={“time”:“2020-05-11T03\:38\:59 2020-05-18T03\:38\:59”,“resolution”:“HOUR”,“locale”:“zh-CN”,“comparisonItem”:[{“geo”:{},“complexKeywordsRestriction”:{“keyword”:[{“type”:“BROAD”,“value”:“NBA”}]}}],“requestOptions”:{“property”:"",“backend”:“CM”,“category”:0}}&token=APP6_UEAAAAAXsNU002YsOS6N9Eb5Z_2BpV-LTY0_AGz&tz=-480 在这个链接中req和token参数需要我们获取的: 获取req,token参数: def get_token(keyword): headers = { 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', 'x-client-data': 'CIu2yQEIo7bJAQjEtskBCKmdygEIy67KAQjQr8oBCLywygEIl7XKAQjttcoBCI66ygEYx7fKAQ==', 'referer': 'https://trends.google.com/trends/explore?date=today%201-m&q=bitcoin,blockchain,eth', 'cookie': '__utmc=10102256; __utma=10102256.31392724.1583402727.1586332529.1586398363.11; __utmz=10102256.1586398363.11.11.utmcsr=shimo.im|utmccn=(referral)|utmcmd=referral|utmcct=/docs/qxW86VTXr8DK6HJX; __utmt=1; __utmb=10102256.9.9.1586398779015; ANID=AHWqTUlRutPWkqC3UpC_-5XoYk6zqoDW3RQX5ePFhLykky73kQ0BpL32ATvqV3O0; CONSENT=WP.284bc1; NID=202=xLozp9-VAAGa2d3d9-cqyqmRjW9nu1zmK0j50IM4pdzJ6wpWTO_Z49JN8W0s1OJ8bySeirh7pSMew1WdqRF890iJLX4HQwwvVkRZ7zwsBDxzeHIx8MOWf27jF0mVCxktZX6OmMmSA0txa0zyJ_AJ3i9gmtEdLeopK5BO3X0LWRA; 1P_JAR=2020-4-9-2' } url = 'https://trends.google.com/trends/api/explore?hl=zh-CN&tz=-480&req={{"comparisonItem":[{{"keyword":"{}","geo":"","time":"now 7-d"}}],"category":0,"property":""}}&tz=-480'.format(keyword) r = requests.get(url, headers=headers) data = json.loads(r.text[5:]) req = data['widgets'][0]['request'] token = data['widgets'][0]['token'] result = {'req':req,'token':token} return result 获取趋势变化图数据: def google(keyword): """谷歌指数""" info = get_token(keyword) req = info['req'] token = info['token'] url = 'https://trends.