-
目录前言场景一:数据不需要频繁的写入mysql场景二:数据是增量的,需要自动化并频繁写入mysql总结前言Python 读取数据自动写入 MySQL 数据库,这个需求在工作中是非常普遍的,主要涉及到 python 操作数据库,读写更新等,数据库可能是 mongodb、 es,他们的处理思路都是相似的,只需要将操作数据库的语法更换即可。本篇文章会给大家系统的分享千万级数据如何写入到 mysql,分为两个场景,两种方式。场景一:数据不需要频繁的写入mysql使用 navicat 工具的导入向导功能。支持多种文件格式,可以根据文件的字段自动建表,也可以在已有表中插入数据,非常快捷方便。场景二:数据是增量的,需要自动化并频繁写入mysql测试数据:csv 格式 ,大约 1200万行123import pandas as pddata = pd.read_csv('./tianchi_mobile_recommend_train_user.csv')data.shape打印结果:方式一:python ➕ pymysql 库安装 pymysql 命令:1pip install pymysql代码实现:12345678910111213141516171819202122232425262728293031import pymysql# 数据库连接信息conn = pymysql.connect( host='127.0.0.1', user='root', passwd='wangyuqing', db='test01', port = 3306, charset="utf8")# 分块处理big_size = 100000# 分块遍历写入到 mysqlwith pd.read_csv('./tianchi_mobile_recommend_train_user.csv',chunksize=big_size) as reader: for df in reader: datas = [] print('处理:',len(df))# print(df) for i ,j in df.iterrows(): data = (j['user_id'],j['item_id'],j['behavior_type'], j['item_category'],j['time']) datas.append(data) _values = ",".join(['%s', ] * 5) sql = """insert into users(user_id,item_id,behavior_type ,item_category,time) values(%s)""" % _values cursor = conn.cursor() cursor.executemany(sql,datas) conn.commit() # 关闭服务conn.close()cursor.close()print('存入成功!')方式二:pandas ➕ sqlalchemy:pandas需要引入sqlalchemy来支持sql,在sqlalchemy的支持下,它可以实现所有常见数据库类型的查询、更新等操作。代码实现:12345from sqlalchemy import create_engineengine = create_engine('mysql+pymysql://root:wangyuqing@localhost:3306/test01')data = pd.read_csv('./tianchi_mobile_recommend_train_user.csv')data.to_sql('user02',engine,chunksize=100000,index=None)print('存入成功!')总结pymysql 方法用时12分47秒,耗时还是比较长的,代码量大,而 pandas 仅需五行代码就实现了这个需求,只用了4分钟左右。最后补充下,方式一需要提前建表,方式二则不需要。所以推荐大家使用第二种方式,既方便又效率高。如果还觉得速度慢的小伙伴,可以考虑加入多进程、多线程。
-
【功能模块】调用python 子脚本,需要使用docx module,调试成功后, 发布。发现无法发现 docx 库。 请帮助! 【操作步骤&问题现象】1、2、【截图信息】【日志信息】(可选,上传日志内容或者附件)[2022-06-28 13:58:01] 启动机器人 3.0.0[2022-06-28 13:58:01] 开始执行[脚本] [四川华测生产][2022-06-28 13:58:01] 开始执行[语句块] [playbackScript.xml 第4行] 遍历/计次循环 [None][2022-06-28 13:58:01] 开始执行[子脚本] [playbackScript.xml 第5行] 调用子脚本 (GetWordFiles.xml) [调用子脚本][2022-06-28 13:58:01] 完成执行[原子命令] [GetWordFiles.xml 第4行] 调用python脚本中的函数 [调用python脚本中的函数] [NOK] [RobotUncaughtError] [系统执行错误: 发生了未捕获异常,详情:ModuleNotFoundError(\"No module named 'docx'\")][2022-06-28 13:58:01] 完成执行[子脚本] [playbackScript.xml 第5行] 调用子脚本 (GetWordFiles.xml) [调用子脚本] [NOK] [RobotUncaughtError] [系统执行错误: 发生了未捕获异常,详情:ModuleNotFoundError(\"No module named 'docx'\")][2022-06-28 13:58:01] 完成执行[语句块] [playbackScript.xml 第4行] 遍历/计次循环 [None] [NOK] [RobotUncaughtError] [系统执行错误: 发生了未捕获异常,详情:ModuleNotFoundError(\"No module named 'docx'\")][2022-06-28 13:58:01] 完成执行[脚本] [四川华测生产] [NOK] [RobotUncaughtError] [系统执行错误: 发生了未捕获异常,详情:ModuleNotFoundError("No module named 'docx'")][2022-06-28 13:58:02] 成功向管理中心发送数据[2022-06-28 13:58:02] 结束机器人
-
np.argpartition 难以解决topKtopK是常用的一个功能,在python中,numpy等计算库使用了丰富的底层优化,对于矩阵计算的效率远高于python的for-loop实现。因此,我们希望尽量用一些numpy函数的组合实现topK。pytorch 库提供了topk函数,可以将高维数组沿某一维度(该维度共N项),选出最大(最小)的K项并排序。返回排序结果和index信息。奇怪的是,更轻量级的numpy库并没有直接提供 topK 函数。numpy只提供了argpartition 和 partition,可以将最大(最小)的K项排到前K位。以argpartition为例,最小的3项排到了前3位:123>>> x = np.array([3, 5, 6, 4, 2, 7, 1])>>> x[np.argpartition(x, 3)]array([2, 1, 3, 4, 5, 7, 6])注意,argpartition实现的是 partial sorting,如上例,前3项和其余项被分开,但是两部分各自都是不排序的!而我们可能更想要topK的几项排好序(其余项则不作要求)。因此,下面提供一种基于argpartition的topK方法。一个naive方法最简单的方法自然是全排序,然后取前K项。缺点在于,要把topK之外的数据也进行排序,当K << N时较为浪费时间,复杂度为O ( n log n ) O(n \log n)O(nlogn):123456789101112131415161718192021222324252627def naive_arg_topK(matrix, K, axis=0): """ perform topK based on np.argsort :param matrix: to be sorted :param K: select and sort the top K items :param axis: dimension to be sorted. :return: """ full_sort = np.argsort(matrix, axis=axis) return full_sort.take(np.arange(K), axis=axis) # Example>>> dists = np.random.permutation(np.arange(30)).reshape(6, 5)array([[17, 28, 1, 24, 23, 8], [ 9, 21, 3, 22, 4, 5], [19, 12, 26, 11, 13, 27], [10, 15, 18, 14, 7, 16], [ 0, 25, 29, 2, 6, 20]])>>> naive_arg_topK(dists, 2, axis=0)array([[4, 2, 0, 4, 1, 1], [1, 3, 1, 2, 4, 0]])>>> naive_arg_topK(dists, 2, axis=1)array([[2, 5], [2, 4], [3, 1], [4, 0], [0, 3]])基于partition的方法对于 np.argpartition 函数,复杂度可能下降到 O ( n log K ) O(n \log K)O(nlogK),很多情况下,K << N,此时naive方法有优化的空间。以下方法首先选出 topK 项,然后仅对前topK项进行排序(matrix仅限2d-array)。def partition_arg_topK(matrix, K, axis=0): """ perform topK based on np.argpartition :param matrix: to be sorted :param K: select and sort the top K items :param axis: 0 or 1. dimension to be sorted. :return: """ a_part = np.argpartition(matrix, K, axis=axis) if axis == 0: row_index = np.arange(matrix.shape[1 - axis]) a_sec_argsort_K = np.argsort(matrix[a_part[0:K, :], row_index], axis=axis) return a_part[0:K, :][a_sec_argsort_K, row_index] else: column_index = np.arange(matrix.shape[1 - axis])[:, None] a_sec_argsort_K = np.argsort(matrix[column_index, a_part[:, 0:K]], axis=axis) return a_part[:, 0:K][column_index, a_sec_argsort_K] # Example>>> dists = np.random.permutation(np.arange(30)).reshape(6, 5)array([[17, 28, 1, 24, 23, 8], [ 9, 21, 3, 22, 4, 5], [19, 12, 26, 11, 13, 27], [10, 15, 18, 14, 7, 16], [ 0, 25, 29, 2, 6, 20]])>>> partition_arg_topK(dists, 2, axis=0)array([[4, 2, 0, 4, 1, 1], [1, 3, 1, 2, 4, 0]])>>> partition_arg_topK(dists, 2, axis=1)array([[2, 5], [2, 4], [3, 1], [4, 0], [0, 3]])大数据量测试对shape(5000, 100000)的矩阵进行topK排序,测试时间为:Kpartition(s)naive(s)108.88422.6041009.01222.45810008.90422.506500011.30522.844# 构建小顶堆跳转def sift(li, low, higt): tmp = li[low] i = low j = 2 * i + 1 while j <= higt: # 情况2:i已经是最后一层 if j + 1 <= higt and li[j + 1] < li[j]: # 右孩子存在并且小于左孩子 j += 1 if tmp > li[j]: li[i] = li[j] i = j j = 2 * i + 1 else: break # 情况1:j位置比tmp小 li[i] = tmp def top_k(li, k): heap = li[0:k] # 建堆 for i in range(k // 2 - 1, -1, -1): sift(heap, i, k - 1) for i in range(k, len(li)): if li[i] > heap[0]: heap[0] = li[i] sift(heap, 0, k - 1) # 挨个输出 for i in range(k - 1, -1, -1): heap[0], heap[i] = heap[i], heap[0] sift(heap, 0, i - 1) return heap li = [0, 8, 6, 2, 4, 9, 1, 4, 6]print(top_k(li, 3))
-
目录一、初始化Counter二、遍历Counter三、elements()四、most_common五、算数操作一、初始化CounterCounter支持3种形式的初始化,比如提供一个数组,一个字典,或单独键值对“=”式赋值。具体初始化的代码如下所示:12345678import collections a = collections.Counter(['a', 'a', 'b', 'b', 'b', 'c'])b = collections.Counter({"a": 2, "b": 3, "c": 1})c = collections.Counter(a=2, b=3, c=1)print(a)print(b)print(c)运行之后,效果如下:这种是直接通过构造函数进行填充。当然,我们还可以直接构造一个空Counter,然后通过update()函数进行填充。12345import collections a = collections.Counter()a.update(['a', 'a', 'b', 'b', 'b', 'c'])print(a)运行效果和上面的a一样,这里就不上图了,感兴趣的读者自己测试运行。二、遍历Counter通过上面初始化以及更新,我们Counter容器中存在了很多的值。因为输出的是字典的形式,所以我们可以直接通过字典的方式进行访问。1234567import collections a = collections.Counter()a.update(['a', 'a', 'b', 'b', 'b', 'c']) for key in 'abcde': print(key, "=", a[key])运行之后,效果如下:可以看到容器Counter,可以输出空值不报错。因为当我们没有找到某个值时,其默认计数为0。三、elements()当然,如果你想实现那种输出没有0值的遍历。可以使用elements()迭代器。具体代码如下:12345import collections a = collections.Counter()a.update('caabbbc')print(list(a.elements()))运行之后,效果如下:需要注意的是,elements()虽然去除了0值,但并不能保证遍历顺序。四、most_commonmost_common()函数可以生成一个序列,统计包含n个最长遇到的输入值以及相应的计数。这里,我们来实现统计一个文档中,字母出现的个数。具体代码如下:12345678import collections c = collections.Counter()with open('英文文档.txt', 'rt') as f: for line in f: c.update(line.rstrip().lower())for letter, count in c.most_common(5): print("{}:{}".format(letter, count))运行之后,效果如下:这里统计的英文文档中,空格最多,达到了658个。其他的一次都是前几最多的个数。这样我们可以通过Counter生成一个英文文档中字母的频度分布,在自然语言的处理当中。就可以完美的结合起来进行统计使用。五、算数操作Counter容器不仅可以统计频度的分布。还可以进行一些算数运算。比如将两个Counter容器进行相加进行统计,亦或者相减也行。具体操作如下:123456789101112import collections c1 = collections.Counter('abcbcabds')c2 = collections.Counter('abcbcabds')print("原始值:")print(c1)print(c2)print("算数运算后:")print(c1 + c2)print(c1 - c2)print(c1 & c2)print(c1 | c2)运行之后,效果如下:
-
目录一、心知天气API密钥获取二、编写代码三、设置为自启动项目一、心知天气API密钥获取首先,访问https://www.seniverse.com,进行登录或者注册操作,然后在控制台上创建一个免费版的项目,创建后,项目信息为:二、编写代码代码如下:12345678910111213141516171819202122232425262728293031323334353637383940import requestsfrom plyer import notification """plyer是用来显示弹窗的模块安装命令:pip install plyer""" params = { "key": "你的API密钥", "location": "ip", # 查询地点设置为访问IP所在地 "language": "zh-Hans", "unit": "c",} url = "https://api.seniverse.com/v3/weather/now.json" # 获取数据r = requests.get(url, params=params) # 解析数据data = r.json()["results"] address = data[0]["location"]['path'] # 地点temperature = data[0]['now']["temperature"] # 温度text = data[0]['now']["text"] # 天气情况 # 弹窗显示消息message = address + " 当前天气:\n" + \ "温度:" + temperature + "℃" + \ "\n天气情况:" + text + \ "\n祝您心情愉悦!(^o^)" """标题为“当前天气”显示10秒钟(timeout参数)"""notification.notify(title="当前天气", message=message, timeout=10)运行代码,可以看到屏幕右下角出现了提示弹窗。三、设置为自启动项目这里我以Windows系统为例,首先,在桌面创建一个bat文件,命名为weather.bat,输入代码:1python D:\Python爬虫\demo.py其中“D:\Python爬虫\demo.py”是我的Python代码路径,你可以根据自己的进行修改。接下来,右击“计算机”,选择“管理”,再找到任务计划程序库,点击右边的“创建基本任务”,如图:接下来,每一次登录这个账号,都会自动启动这个项目,如图,笔者退出账号后,再登录,可以看到右下角出现了弹窗:
-
pandas.Series.cumprod 官方文档cumprod()累积连乘1234Series.cumprod(axis=None, skipna=True, *args, **kwargs)#实现功能:Return cumulative product over a DataFrame or Series axis.#实现功能:Returns a DataFrame or Series of the same size containing the cumulative product.#return:scalar or Seriescumsum()累积连加pandas.Series.prod官方文档123Series.prod(axis=None, skipna=None, level=None, numeric_only=None, min_count=0, **kwargs)# 实现功能:Return the product of the values for the requested axis.# return:scalar or Series优点没看明白,因为常规情况下,所用的.prod()并非pandas下的函数,而是numpy下的函数。numpy.prod官方文档123numpy.prod(a, axis=None, dtype=None, out=None, keepdims=<class numpy._globals._NoValue>)# 实现功能:Return the product of array elements over a given axis.# return:product_along_axis : ndarray返回给定轴上数组元素的乘积。跟cumprod不同,cumprod是计算当前一个累积乘上前面所有的数据,更多是一个list;prod返回的是给定这个轴上最终一个值。补充:【python初学者】简单易懂的图解:np.cumsum和np.cumprod函数到底在干嘛?1.np.cumsum本人是一名python小白,最近过完了python的基本知识后,在看《利用python进行数据分析》这本书,书中cumsum函数一笔带过留下本小白“懵逼树下你和我”,当然是我自己的问题不是书的问题,经过画图理解后渐渐明白了这个函数到底在干么。1.1np.cumsum-轴的概念首先,在学习cumsum函数之前我们应该先明白什么是轴,以下面代码来进行说明:12arr=np.arange(1,17,1).reshape((2,2,4))arr12345array([[[ 1, 2, 3, 4], [ 5, 6, 7, 8]], [[ 9, 10, 11, 12], [13, 14, 15, 16]]])其实数组的轴(axis)就是数组的维度,上面的代码生成了一个224的数组,所以1、这个数组的0轴为2 ,axis=02、这个数组的1轴为2 ,axis=13、这个数组的2轴为4 ,axis=2该数组如图所示(蓝,橙,黄,绿都是2轴,橙和绿上的“2轴”画图时忘了标注):这里还要补充说一下:红色的数字只是因为我用的iPad画图很不方便所以没改成黑色,忽略就好1.2cumsum(axis=0)cumsum作用:计算轴向元素累加和,返回由中间结果组成的数组这句概念中我认为大家理解起来比较难受的地方应该是轴向元素累加。首先,通过前文对轴概念的理解我们可以知道axis=0代表着最外层的维度也就是0轴(这里可能说法不太正确,主要为了配合上节图片),所以就是0轴的累加计算,我们以前文用到的数组为例(红色虚线表示按照0轴进行累加):step1:沿着0轴进行累加代码:12345arr=np.array([[[ 1, 2, 3, 4], [ 5, 6, 7, 8]], [[ 9, 10, 11, 12], [13, 14, 15, 16]]])arr.cumsum(axis=0)结果为:12345array([[[ 1, 2, 3, 4], [ 5, 6, 7, 8]], [[10, 12, 14, 16], [18, 20, 22, 24]]])1.3cumsum(axis=1)这里我们还是以之前举例的数组为例,沿着1轴进行累加(也就是2 * 2 * 4中的第二个2),这里为了方便讲解我将数组的摆放位置换了一下,不影响哈~step1:红色虚线代表我们现在应该沿着1轴进行累加啦!step2:既然沿着1轴进行累加,我们是不是就应该在1轴内部进行累加呢?所以就应该[1,2,3,4]和[5,6,7,8]进行累加,[9,10,11,12]和[13,14,15,16]进行累加代码结果:1234567arr.cumsum(axis=1)#运行结果array([[[ 1, 2, 3, 4], [ 6, 8, 10, 12]], [[ 9, 10, 11, 12], [22, 24, 26, 28]]])1.4cumsum(axis=2)都已经讲到沿着轴2进行累加了,废话就不多说了直接放图,大家看看有没有做对吧step1:老规矩:红色虚线表示沿着2轴进行累加,所以应该是1,2,3,4进行累加,5,6,7,8进行累加,依次类推step2我们以蓝色这一项为例:第一项:1第二项:1+2=3第三项:1+2+3=6第四项:1+2+3+4=10代码结果:1234567arr.cumsum(axis=2)#运行结果array([[[ 1, 3, 6, 10], [ 5, 11, 18, 26]], [[ 9, 19, 30, 42], [13, 27, 42, 58]]])
-
老规矩,先上效果图:理论很简单,就是对图片操作,这里需要用到PIL的python包,里面有很好用的图像处理功能。12img = Image.open(picPath)img = img.resize((picW, picH))然后读取灰度值,再把灰度值和字符对应起来就行。1234567891011121314151617181920from PIL import ImagelstChars = list("$@B%8&WM#*oahkbdpqwmZO0QLaCJUYXzczjhdhsdavunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'.") def oneChars(r, g, b, alpha = 256): global lstChars length = len(lstChars) gray = int(0.2126 * r + 0.7152 * g + 0.722 * b) index =length*gray return lstChars[index]picPath = "C:\Users\Administrator\Desktop\\aaaaa\\aa.png"picH = 40picW = 80img = Image.open(picPath)img = img.resize((picW, picH))txt = ""for y in range(picH): for x in range(picW): txt += oneChars(img.getpixel((x, y))) txt += '\n' print txt
-
目录导语一、简介1.1 软件介绍二、准备中2.0 原理简介2.1 环境安装2.2 素材准备(可修改)三、开始敲代码3.1 导入模块3.2 奔跑的猫-CPU3.3 奔跑的猫-内存四、效果展示导语在使用 Mac 电脑办公时,有时候不知道哪些软件或进程会占用大量的资源,导致进行其他任务时出现变慢、卡顿等现象。因此,实时监控系统的资源就变得非常重要。但是市面上的系统监控软件琳琅满目,种类繁多,哪款监控软件最好?今天小编给大家介绍一款超好用的Mac 监控软件奔跑的猫猫,希望可以对你的选择有所帮助。嗯哼~win10电脑表示不服,Mac能有的,我也不能少,SO 一款治愈系的猫咪监控小程序就做出来啦一、简介1.1 软件介绍用过Mac的可能知道这么一款软件:RunCat。这是一款治愈系的 Mac 系统监控软件,它可以以动画的形式驻留在你的系统状态栏里。猫猫可以通过运行速度告诉你 Mac 的 CPU 使用率。而且 RunCat 为菜单栏提供了关键帧动画,动画根据 Mac 的 CPU 使用情况改变速度。当然 RunCat 不只有猫,还有很多动物和动画,比如:猫 —狗 —猎豹 —兔子 —海豚 —青蛙 —鸟 —企鹅 —很长的龙 —齿轮 ⚙️—火 —水滴 —火箭 —环 ⭕️——等等。这应用就功能来说确实不够有优势,但是架不住它好玩啊。哈哈 小编就喜欢给大家介绍一些好玩儿的东西嘛~另外它自带的免费动画很多,一般来说还是够用的。RunCat 是款更适合无聊发呆时治愈打发时间的软件哦!二、准备中2.0 原理简介原理其实很简单,利用python的psutil包就可以轻松地获取当前电脑的CPU利用率或者运行内存利用率。然后根据利用率来决定托盘图标的更新频率就好啦。然后通过循环设置5个不同状态的icon来实现猫猫跑动的效果,有兴趣的小伙伴可以制作自己喜欢的动画然后替换掉我找到的就OK啦~2.1 环境安装Python3、Pycharm。相关模块:psutil模块;以及一些python自带的模块。模块安装统一使用豆瓣镜像源:pip install -i https://pypi.douban.com/simple/ +模块名2.2 素材准备(可修改)猫猫可以通过运行速度告诉你 Mac 的 CPU 使用率,主要也是猫猫做的小脚本哈,其他的动物可以自己尝试做啦~三、开始敲代码3.1 导入模块12345import sysimport timeimport psutilfrom PyQt5.QtGui import QIconfrom PyQt5.QtWidgets import QApplication, QSystemTrayIcon3.2 奔跑的猫-CPU12345678910111213141516171819202122def runcatCPU(): app = QApplication(sys.argv) # 最后一个可视的窗口退出时程序不退出 app.setQuitOnLastWindowClosed(False) icon = QSystemTrayIcon() icon.setIcon(QIcon('icons/0.png')) icon.setVisible(True) cpu_percent = psutil.cpu_percent(interval=1) / 100 cpu_percent_update_fps = 20 fps_count = 0 while True: fps_count += 1 if fps_count > cpu_percent_update_fps: cpu_percent = psutil.cpu_percent(interval=1) / 100 fps_count = 0 # 开口向上的抛物线, 左边递减 time_interval = (cpu_percent * cpu_percent - 2 * cpu_percent + 2) / 20 for i in range(5): icon.setIcon(QIcon('icons/%d.png' % i)) icon.setToolTip('cpu: %.2f' % cpu_percent) time.sleep(time_interval) app.exec_()3.3 奔跑的猫-内存12345678910111213141516171819202122def runcatMemory(): app = QApplication(sys.argv) # 最后一个可视的窗口退出时程序不退出 app.setQuitOnLastWindowClosed(False) icon = QSystemTrayIcon() icon.setIcon(QIcon('icons/0.png')) icon.setVisible(True) memory_percent = psutil.virtual_memory().percent / 100 memory_percent_update_fps = 20 fps_count = 0 while True: fps_count += 1 if fps_count > memory_percent_update_fps: memory_percent = psutil.virtual_memory().percent / 100 fps_count = 0 # 开口向上的抛物线, 左边递减 time_interval = (memory_percent * memory_percent - 2 * memory_percent + 2) / 20 for i in range(5): icon.setIcon(QIcon('icons/%d.png' % i)) icon.setToolTip('memory: %.2f' % memory_percent) time.sleep(time_interval) app.exec_()四、效果展示静态截图展示效果
-
目录一、单因素分析线性拟合二、实现地理编码一、单因素分析线性拟合功能:线性拟合,单因素分析,对散点图进行线性拟合,并放大散点图的局部位置输入:某个xlsx文件,包含'患者密度(人/10万人)'和'人口密度(人/平方千米)'两列输出:对这两列数据进行线性拟合,绘制散点实现代码:1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768import pandas as pdfrom pylab import mplfrom scipy import optimizeimport numpy as npimport matplotlib.pyplot as pltdef f_1(x, A, B): return A*x + Bdef draw_cure(file): data1=pd.read_excel(file) data1=pd.DataFrame(data1) hz=list(data1['患者密度(人/10万人)']) rk=list(data1['人口密度(人/平方千米)']) hz_gy=[] rk_gy=[] for i in hz: hz_gy.append((i-min(hz))/(max(hz)-min(hz))) for i in rk: rk_gy.append((i-min(rk))/(max(rk)-min(rk))) n=['玄武区','秦淮区','建邺区','鼓楼区','浦口区','栖霞区','雨花台区','江宁区','六合区','溧水区','高淳区', '锡山区','惠山区','滨湖区','梁溪区','新吴区','江阴市','宜兴市', '鼓楼区','云龙区','贾汪区','泉山区','铜山区','丰县','沛县','睢宁县','新沂市','邳州市', '天宁区','钟楼区','新北区','武进区','金坛区','溧阳市', '虎丘区','吴中区','相城区','姑苏区','吴江区','常熟市','张家港市','昆山市','太仓市', '崇川区','港闸区','通州区','如东县','启东市','如皋市','海门市','海安市', '连云区','海州区','赣榆区','东海县','灌云县','灌南县', '淮安区','淮阴区','清江浦区','洪泽区','涟水县','盱眙县','金湖县', '亭湖区','盐都区','大丰区','响水县','滨海县','阜宁县','射阳县','建湖县','东台市', '广陵区','邗江区','江都区','宝应县','仪征市','高邮市', '京口区','润州区','丹徒区','丹阳市','扬中市','句容市', '海陵区','高港区','姜堰区','兴化市','靖江市','泰兴市', '宿城区','宿豫区','沭阳县','泗阳县','泗洪县'] mpl.rcParams['font.sans-serif'] = ['FangSong'] plt.figure(figsize=(16,8),dpi=98) p1 = plt.subplot(121) p2 = plt.subplot(122) p1.scatter(rk_gy,hz_gy,c='r') p2.scatter(rk_gy,hz_gy,c='r') p1.axis([0.0,1.01,0.0,1.01]) p1.set_ylabel("患者密度(人/10万人)",fontsize=13) p1.set_xlabel("人口密度(人/平方千米)",fontsize=13) p1.set_title("人口密度—患者密度相关性",fontsize=13) for i,txt in enumerate(n): p1.annotate(txt,(rk_gy[i],hz_gy[i])) A1, B1 = optimize.curve_fit(f_1, rk_gy, hz_gy)[0] x1 = np.arange(0, 1, 0.01) y1 = A1*x1 + B1 p1.plot(x1, y1, "blue",label='一次拟合直线') x2 = np.arange(0, 1, 0.01) y2 = x2 p1.plot(x2, y2,'g--',label='y=x') p1.legend(loc='upper left',fontsize=13) # # plot the box tx0 = 0;tx1 = 0.1;ty0 = 0;ty1 = 0.2 sx = [tx0,tx1,tx1,tx0,tx0] sy = [ty0,ty0,ty1,ty1,ty0] p1.plot(sx,sy,"purple") p2.axis([0,0.1,0,0.2]) p2.set_ylabel("患者密度(人/10万人)",fontsize=13) p2.set_xlabel("人口密度(人/平方千米)",fontsize=13) p2.set_title("人口密度—患者密度相关性",fontsize=13) for i,txt in enumerate(n): p2.annotate(txt,(rk_gy[i],hz_gy[i])) p2.plot(x1, y1, "blue",label='一次拟合直线') p2.plot(x2, y2,'g--',label='y=x') p2.legend(loc='upper left',fontsize=13) plt.show()if __name__ == '__main__': draw_cure("F:\医学大数据课题\论文终稿修改\scientific report\返修\市区县相关分析 _2231.xls")实现效果:二、实现地理编码输入:中文地址信息,例如安徽为县天城镇都督村冲里18号输出:经纬度坐标,例如107.34799754989581 30.50483335424108功能:根据中文地址信息获取经纬度坐标实现代码:123456789101112131415161718192021222324252627282930313233343536373839404142434445import jsonfrom urllib.request import urlopen,quoteimport xlrddef readXLS(XLS_FILE,sheet0): rb= xlrd.open_workbook(XLS_FILE) rs= rb.sheets()[sheet0] return rsdef getlnglat(adress): url = 'http://api.map.baidu.com/geocoding/v3/?address=' output = 'json' ak = 'fdi11GHN3GYVQdzVnUPuLSScYBVxYDFK' add = quote(adress)#使用quote进行编码 为了防止中文乱码 # add=adress url2 = url + add + '&output=' + output + '&ak=' + ak req = urlopen(url2) res = req.read().decode() temp = json.loads(res) return tempdef getlatlon(sd_rs): nrows_sd_rs=sd_rs.nrows for i in range(4,nrows_sd_rs): # for i in range(4, 7): row=sd_rs.row_values(i) print(i,i/nrows_sd_rs) b = (row[11]+row[12]+row[9]).replace('#','号') # 第三列的地址 print(b) try: lng = getlnglat(b)['result']['location']['lng'] # 获取经度并写入 lat = getlnglat(b)['result']['location']['lat'] #获取纬度并写入 except KeyError as e: lng='' lat='' f_err=open('f_err.txt','a') f_err.write(str(i)+'\t') f_err.close() print(e) print(lng,lat) f_latlon = open('f_latlon.txt', 'a') f_latlon.write(row[0]+'\t'+b+'\t'+str(lng)+'\t'+str(lat)+'\n') f_latlon.close()if __name__=='__main__': # sle_xls_file = 'F:\医学大数据课题\江苏省SLE数据库(两次随访合并).xlsx' sle_xls_file = "F:\医学大数据课题\数据副本\江苏省SLE数据库(两次随访合并) - 副本.xlsx" sle_data_rs = readXLS(sle_xls_file, 1) getlatlon(sle_data_rs)
-
目录python脚本执行的3种方法:方法一:交互模式直接执行语句方法二:通过脚本输出方法三:脚本中指定 python 路径,修改文件为可执行文件总结python脚本执行的3种方法:(找到自己能够使用的方法,能用的方法就是好方法)方法一:交互模式直接执行语句交互模式下直接编写执行 Python语句,不用再创建脚本文件Windows下:打开并进入命令提示符-------->输入python并回车-------->即可进入交互模式Linux 下:打开终端模拟器------->输入python(对应版本号)------>进入交互模式------>输入exit()退出交互模式方法二:通过脚本输出用文本编辑器,编写脚本文件,命名为 xxx.py,在命令行模式下输入 python xxx.py 即可(注意:要进入脚本文件所在路径,或输入脚本文件完整路径)①进入脚本文件所在路径下执行C:\Windows\System32>D:D:\路径>再输入python xxx.py②给出脚本文件的完整路径(windows)C:\Windows\System32>python D:\路径\xxx.py(Linux)他们的斜线方向不一样方法三:脚本中指定 python 路径,修改文件为可执行文件①脚本文件首行添加 #!/路径/python3②添加文件可执行权限123$ chmod u+x xxx.py$ ls -la xxx.py-rwxrw-r-- xxx.py③运行$ ./xxx.py(注意:要在脚本文件中指定解释器,否则无法直接运行脚本文件)
-
目录一、单目三维重建概述二、实现过程(1)相机的标定(2)图像特征提取及匹配(3)三维重建三、结论四、代码总结一、单目三维重建概述客观世界的物体是三维的,而我们用摄像机获取的图像是二维的,但是我们可以通过二维图像感知目标的三维信息。三维重建技术是以一定的方式处理图像进而得到计算机能够识别的三维信息,由此对目标进行分析。而单目三维重建则是根据单个摄像头的运动来模拟双目视觉,从而获得物体在空间中的三维视觉信息,其中,单目即指单个摄像头。二、实现过程在对物体进行单目三维重建的过程中,相关运行环境如下:matplotlib 3.3.4numpy 1.19.5opencv-contrib-python 3.4.2.16opencv-python 3.4.2.16pillow 8.2.0python 3.6.2其重建主要包含以下步骤:(1)相机的标定(2)图像特征提取及匹配(3)三维重建接下来,我们来详细看下每个步骤的具体实现:(1)相机的标定在我们日常生活中有很多相机,如手机上的相机、数码相机及功能模块型相机等等,每一个相机的参数都是不同的,即相机拍出的照片的分辨率、模式等。假设我们在进行物体三维重建的时候,事先并不知道我们相机的矩阵参数,那么,我们就应当计算出相机的矩阵参数,这一个步骤就叫做相机的标定。相机标定的相关原理我就不介绍了,网上很多人都讲解的挺详细的。其标定的具体实现如下:123456789101112131415161718192021222324252627282930def camera_calibration(ImagePath): # 循环中断 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # 棋盘格尺寸(棋盘格的交叉点的个数) row = 11 column = 8 objpoint = np.zeros((row * column, 3), np.float32) objpoint[:, :2] = np.mgrid[0:row, 0:column].T.reshape(-1, 2) objpoints = [] # 3d point in real world space imgpoints = [] # 2d points in image plane. batch_images = glob.glob(ImagePath + '/*.jpg') for i, fname in enumerate(batch_images): img = cv2.imread(batch_images[i]) imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # find chess board corners ret, corners = cv2.findChessboardCorners(imgGray, (row, column), None) # if found, add object points, image points (after refining them) if ret: objpoints.append(objpoint) corners2 = cv2.cornerSubPix(imgGray, corners, (11, 11), (-1, -1), criteria) imgpoints.append(corners2) # Draw and display the corners img = cv2.drawChessboardCorners(img, (row, column), corners2, ret) cv2.imwrite('Checkerboard_Image/Temp_JPG/Temp_' + str(i) + '.jpg', img) print("成功提取:", len(batch_images), "张图片角点!") ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, imgGray.shape[::-1], None, None)其中,cv2.calibrateCamera函数求出的mtx矩阵即为K矩阵。当修改好相应参数并完成标定后,我们可以输出棋盘格的角点图片来看看是否已成功提取棋盘格的角点,输出角点图如下:图1:棋盘格角点提取(2)图像特征提取及匹配在整个三维重建的过程中,这一步是最为关键的,也是最为复杂的一步,图片特征提取的好坏决定了你最后的重建效果。在图片特征点提取算法中,有三种算法较为常用,分别为:SIFT算法、SURF算法以及ORB算法。通过综合分析对比,我们在这一步中采取SURF算法来对图片的特征点进行提取。三种算法的特征点提取效果对比如果大家感兴趣可以去网上搜来看下,在此就不逐一对比了。具体实现如下:1234567891011121314151617181920212223242526272829303132def epipolar_geometric(Images_Path, K): IMG = glob.glob(Images_Path) img1, img2 = cv2.imread(IMG[0]), cv2.imread(IMG[1]) img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # Initiate SURF detector SURF = cv2.xfeatures2d_SURF.create() # compute keypoint & descriptions keypoint1, descriptor1 = SURF.detectAndCompute(img1_gray, None) keypoint2, descriptor2 = SURF.detectAndCompute(img2_gray, None) print("角点数量:", len(keypoint1), len(keypoint2)) # Find point matches bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True) matches = bf.match(descriptor1, descriptor2) print("匹配点数量:", len(matches)) src_pts = np.asarray([keypoint1[m.queryIdx].pt for m in matches]) dst_pts = np.asarray([keypoint2[m.trainIdx].pt for m in matches]) # plot knn_image = cv2.drawMatches(img1_gray, keypoint1, img2_gray, keypoint2, matches[:-1], None, flags=2) image_ = Image.fromarray(np.uint8(knn_image)) image_.save("MatchesImage.jpg") # Constrain matches to fit homography retval, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 100.0) # We select only inlier points points1 = src_pts[mask.ravel() == 1] points2 = dst_pts[mask.ravel() == 1]图2:特征点提取(3)三维重建我们找到图片的特征点并相互匹配后,则可以开始进行三维重建了,具体实现如下:123456789101112131415161718192021222324252627282930313233343536373839404142434445points1 = cart2hom(points1.T)points2 = cart2hom(points2.T)# plotfig, ax = plt.subplots(1, 2)ax[0].autoscale_view('tight')ax[0].imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))ax[0].plot(points1[0], points1[1], 'r.')ax[1].autoscale_view('tight')ax[1].imshow(cv2.cvtColor(img2, cv2.COLOR_BGR2RGB))ax[1].plot(points2[0], points2[1], 'r.')plt.savefig('MatchesPoints.jpg')fig.show()# points1n = np.dot(np.linalg.inv(K), points1)points2n = np.dot(np.linalg.inv(K), points2)E = compute_essential_normalized(points1n, points2n)print('Computed essential matrix:', (-E / E[0][1])) P1 = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])P2s = compute_P_from_essential(E) ind = -1for i, P2 in enumerate(P2s): # Find the correct camera parameters d1 = reconstruct_one_point(points1n[:, 0], points2n[:, 0], P1, P2) # Convert P2 from camera view to world view P2_homogenous = np.linalg.inv(np.vstack([P2, [0, 0, 0, 1]])) d2 = np.dot(P2_homogenous[:3, :4], d1) if d1[2] > 0 and d2[2] > 0: ind = i P2 = np.linalg.inv(np.vstack([P2s[ind], [0, 0, 0, 1]]))[:3, :4]Points3D = linear_triangulation(points1n, points2n, P1, P2) fig = plt.figure()fig.suptitle('3D reconstructed', fontsize=16)ax = fig.gca(projection='3d')ax.plot(Points3D[0], Points3D[1], Points3D[2], 'b.')ax.set_xlabel('x axis')ax.set_ylabel('y axis')ax.set_zlabel('z axis')ax.view_init(elev=135, azim=90)plt.savefig('Reconstruction.jpg')plt.show()其重建效果如下(效果一般):图3:三维重建三、结论从重建的结果来看,单目三维重建效果一般,我认为可能与这几方面因素有关:(1)图片拍摄形式。如果是进行单目三维重建任务,在拍摄图片时最好保持平行移动相机,且最好正面拍摄,即不要斜着拍或特异角度进行拍摄;(2)拍摄时周边环境干扰。选取拍摄的地点最好保持单一,减少无关物体的干扰;(3)拍摄光源问题。选取的拍照场地要保证合适的亮度(具体情况要试才知道你们的光源是否达标),还有就是移动相机的时候也要保证前一时刻和此时刻的光源一致性。其实,单目三维重建的效果确实一般,就算将各方面情况都拉满,可能得到的重建效果也不是特别好。或者我们可以考虑采用双目三维重建,双目三维重建效果肯定是要比单目的效果好的,在实现是也就麻烦一(亿)点点,哈哈。其实也没有多太多的操作,主要就是整两个相机拍摄和标定两个相机麻烦点,其他的都还好。四、代码本次实验的全部代码如下:GitHub:https://github.com/DeepVegChicken/Learning-3DReconstruction123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341import cv2import jsonimport numpy as npimport globfrom PIL import Imageimport matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = False def cart2hom(arr): """ Convert catesian to homogenous points by appending a row of 1s :param arr: array of shape (num_dimension x num_points) :returns: array of shape ((num_dimension+1) x num_points) """ if arr.ndim == 1: return np.hstack([arr, 1]) return np.asarray(np.vstack([arr, np.ones(arr.shape[1])])) def compute_P_from_essential(E): """ Compute the second camera matrix (assuming P1 = [I 0]) from an essential matrix. E = [t]R :returns: list of 4 possible camera matrices. """ U, S, V = np.linalg.svd(E) # Ensure rotation matrix are right-handed with positive determinant if np.linalg.det(np.dot(U, V)) < 0: V = -V # create 4 possible camera matrices (Hartley p 258) W = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]]) P2s = [np.vstack((np.dot(U, np.dot(W, V)).T, U[:, 2])).T, np.vstack((np.dot(U, np.dot(W, V)).T, -U[:, 2])).T, np.vstack((np.dot(U, np.dot(W.T, V)).T, U[:, 2])).T, np.vstack((np.dot(U, np.dot(W.T, V)).T, -U[:, 2])).T] return P2s def correspondence_matrix(p1, p2): p1x, p1y = p1[:2] p2x, p2y = p2[:2] return np.array([ p1x * p2x, p1x * p2y, p1x, p1y * p2x, p1y * p2y, p1y, p2x, p2y, np.ones(len(p1x)) ]).T return np.array([ p2x * p1x, p2x * p1y, p2x, p2y * p1x, p2y * p1y, p2y, p1x, p1y, np.ones(len(p1x)) ]).T def scale_and_translate_points(points): """ Scale and translate image points so that centroid of the points are at the origin and avg distance to the origin is equal to sqrt(2). :param points: array of homogenous point (3 x n) :returns: array of same input shape and its normalization matrix """ x = points[0] y = points[1] center = points.mean(axis=1) # mean of each row cx = x - center[0] # center the points cy = y - center[1] dist = np.sqrt(np.power(cx, 2) + np.power(cy, 2)) scale = np.sqrt(2) / dist.mean() norm3d = np.array([ [scale, 0, -scale * center[0]], [0, scale, -scale * center[1]], [0, 0, 1] ]) return np.dot(norm3d, points), norm3d def compute_image_to_image_matrix(x1, x2, compute_essential=False): """ Compute the fundamental or essential matrix from corresponding points (x1, x2 3*n arrays) using the 8 point algorithm. Each row in the A matrix below is constructed as [x'*x, x'*y, x', y'*x, y'*y, y', x, y, 1] """ A = correspondence_matrix(x1, x2) # compute linear least square solution U, S, V = np.linalg.svd(A) F = V[-1].reshape(3, 3) # constrain F. Make rank 2 by zeroing out last singular value U, S, V = np.linalg.svd(F) S[-1] = 0 if compute_essential: S = [1, 1, 0] # Force rank 2 and equal eigenvalues F = np.dot(U, np.dot(np.diag(S), V)) return F def compute_normalized_image_to_image_matrix(p1, p2, compute_essential=False): """ Computes the fundamental or essential matrix from corresponding points using the normalized 8 point algorithm. :input p1, p2: corresponding points with shape 3 x n :returns: fundamental or essential matrix with shape 3 x 3 """ n = p1.shape[1] if p2.shape[1] != n: raise ValueError('Number of points do not match.') # preprocess image coordinates p1n, T1 = scale_and_translate_points(p1) p2n, T2 = scale_and_translate_points(p2) # compute F or E with the coordinates F = compute_image_to_image_matrix(p1n, p2n, compute_essential) # reverse preprocessing of coordinates # We know that P1' E P2 = 0 F = np.dot(T1.T, np.dot(F, T2)) return F / F[2, 2] def compute_fundamental_normalized(p1, p2): return compute_normalized_image_to_image_matrix(p1, p2) def compute_essential_normalized(p1, p2): return compute_normalized_image_to_image_matrix(p1, p2, compute_essential=True) def skew(x): """ Create a skew symmetric matrix *A* from a 3d vector *x*. Property: np.cross(A, v) == np.dot(x, v) :param x: 3d vector :returns: 3 x 3 skew symmetric matrix from *x* """ return np.array([ [0, -x[2], x[1]], [x[2], 0, -x[0]], [-x[1], x[0], 0] ]) def reconstruct_one_point(pt1, pt2, m1, m2): """ pt1 and m1 * X are parallel and cross product = 0 pt1 x m1 * X = pt2 x m2 * X = 0 """ A = np.vstack([ np.dot(skew(pt1), m1), np.dot(skew(pt2), m2) ]) U, S, V = np.linalg.svd(A) P = np.ravel(V[-1, :4]) return P / P[3] def linear_triangulation(p1, p2, m1, m2): """ Linear triangulation (Hartley ch 12.2 pg 312) to find the 3D point X where p1 = m1 * X and p2 = m2 * X. Solve AX = 0. :param p1, p2: 2D points in homo. or catesian coordinates. Shape (3 x n) :param m1, m2: Camera matrices associated with p1 and p2. Shape (3 x 4) :returns: 4 x n homogenous 3d triangulated points """ num_points = p1.shape[1] res = np.ones((4, num_points)) for i in range(num_points): A = np.asarray([ (p1[0, i] * m1[2, :] - m1[0, :]), (p1[1, i] * m1[2, :] - m1[1, :]), (p2[0, i] * m2[2, :] - m2[0, :]), (p2[1, i] * m2[2, :] - m2[1, :]) ]) _, _, V = np.linalg.svd(A) X = V[-1, :4] res[:, i] = X / X[3] return res def writetofile(dict, path): for index, item in enumerate(dict): dict[item] = np.array(dict[item]) dict[item] = dict[item].tolist() js = json.dumps(dict) with open(path, 'w') as f: f.write(js) print("参数已成功保存到文件") def readfromfile(path): with open(path, 'r') as f: js = f.read() mydict = json.loads(js) print("参数读取成功") return mydict def camera_calibration(SaveParamPath, ImagePath): # 循环中断 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # 棋盘格尺寸 row = 11 column = 8 objpoint = np.zeros((row * column, 3), np.float32) objpoint[:, :2] = np.mgrid[0:row, 0:column].T.reshape(-1, 2) objpoints = [] # 3d point in real world space imgpoints = [] # 2d points in image plane. batch_images = glob.glob(ImagePath + '/*.jpg') for i, fname in enumerate(batch_images): img = cv2.imread(batch_images[i]) imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # find chess board corners ret, corners = cv2.findChessboardCorners(imgGray, (row, column), None) # if found, add object points, image points (after refining them) if ret: objpoints.append(objpoint) corners2 = cv2.cornerSubPix(imgGray, corners, (11, 11), (-1, -1), criteria) imgpoints.append(corners2) # Draw and display the corners img = cv2.drawChessboardCorners(img, (row, column), corners2, ret) cv2.imwrite('Checkerboard_Image/Temp_JPG/Temp_' + str(i) + '.jpg', img) print("成功提取:", len(batch_images), "张图片角点!") ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, imgGray.shape[::-1], None, None) dict = {'ret': ret, 'mtx': mtx, 'dist': dist, 'rvecs': rvecs, 'tvecs': tvecs} writetofile(dict, SaveParamPath) meanError = 0 for i in range(len(objpoints)): imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist) error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2) / len(imgpoints2) meanError += error print("total error: ", meanError / len(objpoints)) def epipolar_geometric(Images_Path, K): IMG = glob.glob(Images_Path) img1, img2 = cv2.imread(IMG[0]), cv2.imread(IMG[1]) img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # Initiate SURF detector SURF = cv2.xfeatures2d_SURF.create() # compute keypoint & descriptions keypoint1, descriptor1 = SURF.detectAndCompute(img1_gray, None) keypoint2, descriptor2 = SURF.detectAndCompute(img2_gray, None) print("角点数量:", len(keypoint1), len(keypoint2)) # Find point matches bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True) matches = bf.match(descriptor1, descriptor2) print("匹配点数量:", len(matches)) src_pts = np.asarray([keypoint1[m.queryIdx].pt for m in matches]) dst_pts = np.asarray([keypoint2[m.trainIdx].pt for m in matches]) # plot knn_image = cv2.drawMatches(img1_gray, keypoint1, img2_gray, keypoint2, matches[:-1], None, flags=2) image_ = Image.fromarray(np.uint8(knn_image)) image_.save("MatchesImage.jpg") # Constrain matches to fit homography retval, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 100.0) # We select only inlier points points1 = src_pts[mask.ravel() == 1] points2 = dst_pts[mask.ravel() == 1] points1 = cart2hom(points1.T) points2 = cart2hom(points2.T) # plot fig, ax = plt.subplots(1, 2) ax[0].autoscale_view('tight') ax[0].imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)) ax[0].plot(points1[0], points1[1], 'r.') ax[1].autoscale_view('tight') ax[1].imshow(cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)) ax[1].plot(points2[0], points2[1], 'r.') plt.savefig('MatchesPoints.jpg') fig.show() # points1n = np.dot(np.linalg.inv(K), points1) points2n = np.dot(np.linalg.inv(K), points2) E = compute_essential_normalized(points1n, points2n) print('Computed essential matrix:', (-E / E[0][1])) P1 = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]) P2s = compute_P_from_essential(E) ind = -1 for i, P2 in enumerate(P2s): # Find the correct camera parameters d1 = reconstruct_one_point(points1n[:, 0], points2n[:, 0], P1, P2) # Convert P2 from camera view to world view P2_homogenous = np.linalg.inv(np.vstack([P2, [0, 0, 0, 1]])) d2 = np.dot(P2_homogenous[:3, :4], d1) if d1[2] > 0 and d2[2] > 0: ind = i P2 = np.linalg.inv(np.vstack([P2s[ind], [0, 0, 0, 1]]))[:3, :4] Points3D = linear_triangulation(points1n, points2n, P1, P2) return Points3D def main(): CameraParam_Path = 'CameraParam.txt' CheckerboardImage_Path = 'Checkerboard_Image' Images_Path = 'SubstitutionCalibration_Image/*.jpg' # 计算相机参数 camera_calibration(CameraParam_Path, CheckerboardImage_Path) # 读取相机参数 config = readfromfile(CameraParam_Path) K = np.array(config['mtx']) # 计算3D点 Points3D = epipolar_geometric(Images_Path, K) # 重建3D点 fig = plt.figure() fig.suptitle('3D reconstructed', fontsize=16) ax = fig.gca(projection='3d') ax.plot(Points3D[0], Points3D[1], Points3D[2], 'b.') ax.set_xlabel('x axis') ax.set_ylabel('y axis') ax.set_zlabel('z axis') ax.view_init(elev=135, azim=90) plt.savefig('Reconstruction.jpg') plt.show() if __name__ == '__main__': main()
-
目录一、绘制带趋势线的散点图二、绘制边缘直方图一、绘制带趋势线的散点图实现功能:在散点图上添加趋势线(线性拟合线)反映两个变量是正相关、负相关或者无相关关系。实现代码:123456789101112131415161718192021222324252627282930313233import pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltimport seaborn as snsimport warningswarnings.filterwarnings(action='once')plt.style.use('seaborn-whitegrid')sns.set_style("whitegrid")print(mpl.__version__)print(sns.__version__)def draw_scatter(file): # Import Data df = pd.read_csv(file) df_select = df.loc[df.cyl.isin([4, 8]), :] # Plot gridobj = sns.lmplot( x="displ", y="hwy", hue="cyl", data=df_select, height=7, aspect=1.6, palette='Set1', scatter_kws=dict(s=60, linewidths=.7, edgecolors='black')) # Decorations sns.set(style="whitegrid", font_scale=1.5) gridobj.set(xlim=(0.5, 7.5), ylim=(10, 50)) gridobj.fig.set_size_inches(10, 6) plt.tight_layout() plt.title("Scatterplot with line of best fit grouped by number of cylinders") plt.show()draw_scatter("F:\数据杂坛\datasets\mpg_ggplot2.csv")实现效果:在散点图上添加趋势线(线性拟合线)反映两个变量是正相关、负相关或者无相关关系。红蓝两组数据分别绘制出最佳的线性拟合线。二、绘制边缘直方图实现功能:python绘制边缘直方图,用于展示X和Y之间的关系、及X和Y的单变量分布情况,常用于数据探索分析。实现代码:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657import pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltimport seaborn as snsimport warningswarnings.filterwarnings(action='once')plt.style.use('seaborn-whitegrid')sns.set_style("whitegrid")print(mpl.__version__)print(sns.__version__)def draw_Marginal_Histogram(file): # Import Data df = pd.read_csv(file) # Create Fig and gridspec fig = plt.figure(figsize=(10, 6), dpi=100) grid = plt.GridSpec(4, 4, hspace=0.5, wspace=0.2) # Define the axes ax_main = fig.add_subplot(grid[:-1, :-1]) ax_right = fig.add_subplot(grid[:-1, -1], xticklabels=[], yticklabels=[]) ax_bottom = fig.add_subplot(grid[-1, 0:-1], xticklabels=[], yticklabels=[]) # Scatterplot on main ax ax_main.scatter('displ', 'hwy', s=df.cty * 4, c=df.manufacturer.astype('category').cat.codes, alpha=.9, data=df, cmap="Set1", edgecolors='gray', linewidths=.5) # histogram on the right ax_bottom.hist(df.displ, 40, histtype='stepfilled', orientation='vertical', color='#098154') ax_bottom.invert_yaxis() # histogram in the bottom ax_right.hist(df.hwy, 40, histtype='stepfilled', orientation='horizontal', color='#098154') # Decorations ax_main.set(title='Scatterplot with Histograms \n displ vs hwy', xlabel='displ', ylabel='hwy') ax_main.title.set_fontsize(10) for item in ([ax_main.xaxis.label, ax_main.yaxis.label] + ax_main.get_xticklabels() + ax_main.get_yticklabels()): item.set_fontsize(10) xlabels = ax_main.get_xticks().tolist() ax_main.set_xticklabels(xlabels) plt.show()draw_Marginal_Histogram("F:\数据杂坛\datasets\mpg_ggplot2.csv")实现效果:
-
像我这种喜欢动物,但不是 那么 喜欢清理那种……新陈代谢的产物的人,桌面宠物就真的是一大福音了当然,我可不是一位称职的“铲屎官”(???)所以我最近就做出了一个功能还算齐全的桌面宠物功能如下:1.在桌面走来走去,或者打个盹;2.左键单击它可以打开功能页;3.有天气预报;4.有语言微聊(得登录图灵账号,但私信我免费拿账号密码);5.一些有趣的天气提示。好了,解析源码↓import tkinterimport osimport randomfrom platform import systemimport easyguiimport requestsfrom bs4 import BeautifulSoupimport tkinterfrom prettytable import PrettyTable这里是导入一些库↑def weather(self): url = f'http://wthrcdn.etouch.cn/weather_mini?citykey=101281601' res = requests.get(url) res.encoding = 'utf-8' res_json = res.json() # 2、数据格式化 data = res_json['data'] city = f"城市:{data['city']}\n" # 字符串格式化的一种方式 f"{}" 通过字典传递值 today = data['forecast'][0] date = f"日期:{today['date']}\n" # \n 换行 now = f"实时温度:{data['wendu']}度\n" temperature = f"波动范围:{today['high']} {today['low']}\n" fengxiang = f"风向:{today['fengxiang']}\n" type = f"天气:{today['type']}\n" tips = f"提醒:{data['ganmao']}\n" result = city + date + now + temperature + fengxiang + type + tips return result这些就是关于天气小贴士的东西↑ def getHTMLText(self,url,timeout = 30): try: r = requests.get(url, timeout = 30) #用requests抓取网页信息 r.raise_for_status() #可以让程序产生异常时停止程序 r.encoding = r.apparent_encoding return r.text except: return '产生异常' def get_data(self,html): final_list = [] soup = BeautifulSoup(html,'html.parser') #用BeautifulSoup库解析网页 body = soup.body data = body.find('div',{'id':'7d'}) ul = data.find('ul') lis = ul.find_all('li') for day in lis: temp_list = [] date = day.find('h1').string #找到日期 temp_list.append(date) info = day.find_all('p') #找到所有的p标签 temp_list.append(info[0].string) if info[1].find('span') is None: #找到p标签中的第二个值'span'标签——最高温度 temperature_highest = ' ' #用一个判断是否有最高温度 else: temperature_highest = info[1].find('span').string temperature_highest = temperature_highest.replace('℃',' ') if info[1].find('i') is None: #找到p标签中的第二个值'i'标签——最高温度 temperature_lowest = ' ' #用一个判断是否有最低温度 else: temperature_lowest = info[1].find('i').string temperature_lowest = temperature_lowest.replace('℃',' ') temp_list.append(temperature_highest) #将最高气温添加到temp_list中 temp_list.append(temperature_lowest) #将最低气温添加到temp_list中 wind_scale = info[2].find('i').string #找到p标签的第三个值'i'标签——风级,添加到temp_list中 temp_list.append(wind_scale) final_list.append(temp_list) #将temp_list列表添加到final_list列表中 return final_list def print_data(self,final_list,num): a="{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format('日期','天气','最高温度','最低温度','风级') for i in range(num): final = final_list[i] a=a+"\n"+"{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format(final[0],final[1],final[2],final[3],final[4]) print(a) #用main()主函数将模块连接 def main(self): url = 'http://www.weather.com.cn/weather/101281601.shtml' html = pet.getHTMLText(url) final_list = pet.get_data(html) pet.print_data(final_list,7)这些就是爬虫抓包↑(这是我这的天气抓包,main函数中url地址后面16进制的数字改一改即可) def __init__(self): self.root = tkinter.Tk() # create window self.delay = 200 # delay in ms self.pixels_from_right = 200 # change to move the pet's starting position self.pixels_from_bottom = 200 # change to move the pet's starting position self.move_speed = 6 # change how fast the pet moves in pixels # initialize frame arrays self.animation = dict( idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle.gif'), format = 'gif -index %i' % i) for i in range(5)], idle_to_sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle-to-sleep.gif'), format = 'gif -index %i' % i) for i in range(8)], sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep.gif'), format = 'gif -index %i' % i) for i in range(3)]*3, sleep_to_idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep-to-idle.gif'), format = 'gif -index %i' % i) for i in range(8)], walk_left = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-left.gif'), format = 'gif -index %i' % i) for i in range(8)], walk_right = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-right.gif'),format = 'gif -index %i' % i) for i in range(8)] ) # window configuration self.root.overrideredirect(True) # remove UI if system() == 'Windows': self.root.wm_attributes('-transparent','black') else: # platform is Mac/Linux # https://stackoverflow.com/questions/19080499/transparent-background-in-a-tkinter-window self.root.wm_attributes('-transparent', True) # do this for mac, but the bg stays black self.root.config(bg='systemTransparent') self.root.attributes('-topmost', True) # put window on top self.root.bind("<Button-1>", self.onLeftClick) self.root.bind("<Button-2>", self.onRightClick) self.root.bind("<Button-3>", self.onRightClick) self.root.bind("<Key>", self.onKeyPress) self.label = tkinter.Label(self.root,bd=0,bg='black') # borderless window if system() != 'Windows': self.label.config(bg='systemTransparent') self.label.pack() screen_width = self.root.winfo_screenwidth() # width of the entire screen screen_height = self.root.winfo_screenheight() # height of the entire screen self.min_width = 10 # do not let the pet move beyond this point self.max_width = screen_width-110 # do not let the pet move beyond this point # change starting properties of the window self.curr_width = screen_width-self.pixels_from_right self.curr_height = screen_height-self.pixels_from_bottom self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height)) def update(self, i, curr_animation): # print("Curently: %s" % curr_animation) self.root.attributes('-topmost', True) # put window on top animation_arr = self.animation[curr_animation] frame = animation_arr[i] self.label.configure(image=frame) # move the pet if needed if curr_animation in ('walk_left', 'walk_right'): self.move_window(curr_animation) i += 1 if i == len(animation_arr): # reached end of this animation, decide on the next animation next_animation = self.getNextAnimation(curr_animation) self.root.after(self.delay, self.update, 0, next_animation) else: self.root.after(self.delay, self.update, i, curr_animation)这些就是建一个透明tkinter窗口,把gif塞进去↑ def onLeftClick(self, event): print("detected left click") a=easygui.choicebox(msg=pet.weather(),title="",choices=["天气预报","语音微聊"]) if a =="天气预报": pet.main() elif a=="语音微聊": newchat="你好" chat="(聊天记录已清空)" API_KEY=""#账号要注册 API_SECRET="" person="我" while True: if not len(chat) >= 100: if newchat: url=('http://i.itpk.cn/api.php?question='+newchat+"&api_key="+API_KEY+"&api_secret="+API_SECRET) file=requests.get(url)#获取网页代码文件 data=file.text#把代码转换成文字 chat=chat+"\n"+person+":"+newchat+"\n"+"小睿:"+data#说话 else: pet.run() newchat=easygui.textbox(chat,"和小睿的聊天") else: chat=""这里就是主控制台,连接一下天气、机器人之类的东西↑ def onRightClick(self, event): self.quit() quit() def onKeyPress(self, event): if event.char in ('q', 'Q'): self.quit() def move_window(self, curr_animation): if curr_animation == 'walk_left': if self.curr_width > self.min_width: self.curr_width -= self.move_speed elif curr_animation == 'walk_right': if self.curr_width < self.max_width: self.curr_width += self.move_speed self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height)) def getNextAnimation(self, curr_animation): if curr_animation == 'idle': return random.choice(['idle', 'idle_to_sleep', 'walk_left', 'walk_right']) elif curr_animation == 'idle_to_sleep': return 'sleep' elif curr_animation == 'sleep': return random.choice(['sleep', 'sleep_to_idle']) elif curr_animation == 'sleep_to_idle': return 'idle' elif curr_animation == 'walk_left': return random.choice(['idle', 'walk_left', 'walk_right']) elif curr_animation == 'walk_right': return random.choice(['idle', 'walk_left', 'walk_right']) def run(self): self.root.after(self.delay, self.update, 0, 'idle') # start on idle self.root.mainloop() def quit(self): self.root.destroy()这些就是触发事件了(左右键单击)↑if __name__ == '__main__': print('Initializing your desktop pet...') print('To quit, right click on the pet') pet = Pet() pet.run()这些就很简单了,主函数召唤class pet↑源码如下:import tkinterimport osimport randomfrom platform import systemimport easyguiimport requestsfrom bs4 import BeautifulSoupimport tkinterfrom prettytable import PrettyTableclass Pet: def weather(self): url = f'http://wthrcdn.etouch.cn/weather_mini?citykey=101281601' res = requests.get(url) res.encoding = 'utf-8' res_json = res.json() # 2、数据格式化 data = res_json['data'] city = f"城市:{data['city']}\n" # 字符串格式化的一种方式 f"{}" 通过字典传递值 today = data['forecast'][0] date = f"日期:{today['date']}\n" # \n 换行 now = f"实时温度:{data['wendu']}度\n" temperature = f"波动范围:{today['high']} {today['low']}\n" fengxiang = f"风向:{today['fengxiang']}\n" type = f"天气:{today['type']}\n" tips = f"提醒:{data['ganmao']}\n" result = city + date + now + temperature + fengxiang + type + tips return result def getHTMLText(self,url,timeout = 30): try: r = requests.get(url, timeout = 30) #用requests抓取网页信息 r.raise_for_status() #可以让程序产生异常时停止程序 r.encoding = r.apparent_encoding return r.text except: return '产生异常' def get_data(self,html): final_list = [] soup = BeautifulSoup(html,'html.parser') #用BeautifulSoup库解析网页 body = soup.body data = body.find('div',{'id':'7d'}) ul = data.find('ul') lis = ul.find_all('li') for day in lis: temp_list = [] date = day.find('h1').string #找到日期 temp_list.append(date) info = day.find_all('p') #找到所有的p标签 temp_list.append(info[0].string) if info[1].find('span') is None: #找到p标签中的第二个值'span'标签——最高温度 temperature_highest = ' ' #用一个判断是否有最高温度 else: temperature_highest = info[1].find('span').string temperature_highest = temperature_highest.replace('℃',' ') if info[1].find('i') is None: #找到p标签中的第二个值'i'标签——最高温度 temperature_lowest = ' ' #用一个判断是否有最低温度 else: temperature_lowest = info[1].find('i').string temperature_lowest = temperature_lowest.replace('℃',' ') temp_list.append(temperature_highest) #将最高气温添加到temp_list中 temp_list.append(temperature_lowest) #将最低气温添加到temp_list中 wind_scale = info[2].find('i').string #找到p标签的第三个值'i'标签——风级,添加到temp_list中 temp_list.append(wind_scale) final_list.append(temp_list) #将temp_list列表添加到final_list列表中 return final_list def print_data(self,final_list,num): a="{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format('日期','天气','最高温度','最低温度','风级') for i in range(num): final = final_list[i] a=a+"\n"+"{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format(final[0],final[1],final[2],final[3],final[4]) print(a) #用main()主函数将模块连接 def main(self): url = 'http://www.weather.com.cn/weather/101281601.shtml' html = pet.getHTMLText(url) final_list = pet.get_data(html) pet.print_data(final_list,7) def __init__(self): self.root = tkinter.Tk() # create window self.delay = 200 # delay in ms self.pixels_from_right = 200 # change to move the pet's starting position self.pixels_from_bottom = 200 # change to move the pet's starting position self.move_speed = 6 # change how fast the pet moves in pixels # initialize frame arrays self.animation = dict( idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle.gif'), format = 'gif -index %i' % i) for i in range(5)], idle_to_sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle-to-sleep.gif'), format = 'gif -index %i' % i) for i in range(8)], sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep.gif'), format = 'gif -index %i' % i) for i in range(3)]*3, sleep_to_idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep-to-idle.gif'), format = 'gif -index %i' % i) for i in range(8)], walk_left = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-left.gif'), format = 'gif -index %i' % i) for i in range(8)], walk_right = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-right.gif'),format = 'gif -index %i' % i) for i in range(8)] ) # window configuration self.root.overrideredirect(True) # remove UI if system() == 'Windows': self.root.wm_attributes('-transparent','black') else: # platform is Mac/Linux # https://stackoverflow.com/questions/19080499/transparent-background-in-a-tkinter-window self.root.wm_attributes('-transparent', True) # do this for mac, but the bg stays black self.root.config(bg='systemTransparent') self.root.attributes('-topmost', True) # put window on top self.root.bind("<Button-1>", self.onLeftClick) self.root.bind("<Button-2>", self.onRightClick) self.root.bind("<Button-3>", self.onRightClick) self.root.bind("<Key>", self.onKeyPress) self.label = tkinter.Label(self.root,bd=0,bg='black') # borderless window if system() != 'Windows': self.label.config(bg='systemTransparent') self.label.pack() screen_width = self.root.winfo_screenwidth() # width of the entire screen screen_height = self.root.winfo_screenheight() # height of the entire screen self.min_width = 10 # do not let the pet move beyond this point self.max_width = screen_width-110 # do not let the pet move beyond this point # change starting properties of the window self.curr_width = screen_width-self.pixels_from_right self.curr_height = screen_height-self.pixels_from_bottom self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height)) def update(self, i, curr_animation): # print("Curently: %s" % curr_animation) self.root.attributes('-topmost', True) # put window on top animation_arr = self.animation[curr_animation] frame = animation_arr[i] self.label.configure(image=frame) # move the pet if needed if curr_animation in ('walk_left', 'walk_right'): self.move_window(curr_animation) i += 1 if i == len(animation_arr): # reached end of this animation, decide on the next animation next_animation = self.getNextAnimation(curr_animation) self.root.after(self.delay, self.update, 0, next_animation) else: self.root.after(self.delay, self.update, i, curr_animation) def onLeftClick(self, event): print("detected left click") a=easygui.choicebox(msg=pet.weather(),title="",choices=["天气预报","语音微聊"]) if a =="天气预报": pet.main() elif a=="语音微聊": newchat="你好" chat="(聊天记录已清空)" API_KEY=""#记得登录,否则报错 API_SECRET="" while True: if newchat: url=('http://i.itpk.cn/api.php?question='+newchat+"&api_key="+API_KEY+"&api_secret="+API_SECRET) file=requests.get(url)#获取网页代码文件 data=file.text#把代码转换成文字 chat=chat+"\n"+person+":"+newchat+"\n"+"机器人:"+data#说话 else: onLeftClick(event) newchat=easygui.textbox(chat,"和智能机器人的聊天") def onRightClick(self, event): self.quit() quit() def onKeyPress(self, event): if event.char in ('q', 'Q'): self.quit() def move_window(self, curr_animation): if curr_animation == 'walk_left': if self.curr_width > self.min_width: self.curr_width -= self.move_speed elif curr_animation == 'walk_right': if self.curr_width < self.max_width: self.curr_width += self.move_speed self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height)) def getNextAnimation(self, curr_animation): if curr_animation == 'idle': return random.choice(['idle', 'idle_to_sleep', 'walk_left', 'walk_right']) elif curr_animation == 'idle_to_sleep': return 'sleep' elif curr_animation == 'sleep': return random.choice(['sleep', 'sleep_to_idle']) elif curr_animation == 'sleep_to_idle': return 'idle' elif curr_animation == 'walk_left': return random.choice(['idle', 'walk_left', 'walk_right']) elif curr_animation == 'walk_right': return random.choice(['idle', 'walk_left', 'walk_right']) def run(self): self.root.after(self.delay, self.update, 0, 'idle') # start on idle self.root.mainloop() def quit(self): self.root.destroy() if __name__ == '__main__': print('Initializing your desktop pet...') print('To quit, right click on the pet') pet = Pet() pet.run()拿(留)走(下)不(评)谢(论)记得关注鸭注:模板来自GitHub - tommyli3318/desktop-pet: An animated pet that moves around on your desktop, using tkinter in Pythonhttps://github.com/tommyli3318/desktop-pet但不超过20%,不算侵权哈 ————————————————版权声明:本文为CSDN博主「无聊的木子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/HI_REY/article/details/124544277
-
1、java的商业化公司支持多,如sap,oracle,ibm等,有商业化的容器,中间件,企业框架ejb。python的开源组织支持多,如qt,linux,google,很多开源程序都支持python, 如pyqt,redis,spark等。2、java主要用于商业逻辑强的领域,如商城系统,erp,oa,金融,保险等传统数据库事务领域,通过类似ssh框架事务代码,对商业数据库,如oralce,db2,sql server等支持较好,软件工程理念较强,适合软件工程式的多人开发模式。python主要用于web数据分析,科学计算,金融分析,信号分析,图像算法,数学计算,统计分析,算法建模,服务器运维,自动化操作,快速开发理念强,适合快速开发团队或个人敏捷模式。3、python有很多虚拟机实现,如cython,Pyston,pypy,jython, IronPython等等,适合用于业务语言,或插件语言,或面向领域语言,而java因为虚拟机巨大,很少用于插件语言,发布也不方便。4、python虚拟机没有java强,java虚拟机是java的核心,python的核心是可以很方便地使用c语言函数或c++库。5、python是全动态性的,可以在运行时自己修改自己的代码,java只能通过变通方法实现。python的变量是动态的,而java的变量是静态的,需要事先声明,所以java ide的代码提示功能优于python ide。6,python的产生几十年了,几十年前面向过程是主流,所以用python有好多程序用的是面向过程设计方法,很多概念从c语言过来的,class在python中是后加入的,而java是为了实现没有指针的c++(当年com组件用的引用记数,java用的虚拟机),主要采用面向对象的设计方法,很多概念是oop的概念。面向过程,相对简洁直观,但容易设计出面条程序,面向对象,相对抽象优雅,但容易过度抽象。7,在实际使用的python入门简单,但要学会用python干活,需要再学习python各种库,pyhton的强大在于库,为什么python的库强大,原因是python的库可以用python,c语言,c++等设计,再提供给python使用,所以无论gpu运行,神经网络,智能算法,数据分析,图像处理,科学计算,各式各样的库在等着你用。而java没有python那么多的开源库,很多库是商业公司内部使用,或发布出来只是一个jar包,看不到原始代码。python虚拟机因为编译性没有java的支持的好(或者说故意这么设计的),一般直接使用源码(linux),或源码简单打个包(如pyexe)。实例:在java类中直接执行python语句如:maven添加依赖<dependency> <groupId>org.python</groupId> <artifactId>jython-standalone</artifactId> <version>2.7.0</version></dependency>在java类中写python语句PythonInterpreter interpreter = new PythonInterpreter();interpreter.exec("menu=[1,2,3,5,6,7]; ");interpreter.exec("print(sorted(menu));"); interpreter.exec("print sorted(menu);");
-
为什么我们从 Python 切换到 Go原文链接:https://softwareengineeringdaily.com/2021/03/03/why-we-switched-from-python-to-go/转换到一种新的语言总是一个很大的步骤,尤其是当你的团队成员中只有一个人有这种语言的经验时。今年早些时候,我们将 Stream 的主要编程语言从 Python 转换到了 Go。这篇文章将解释为什么我们决定放弃 Python 转而使用 Go 的一些原因。原因 1 – 性能Go 非常快。性能类似于 Java 或 C++。对于我们的用例,Go 通常比 Python 快 40 倍。这是一个比较Go 和 Python的小型基准测试游戏。原因 2 – 语言表现很重要对于许多应用程序来说,编程语言只是应用程序和数据库之间的粘合剂。语言本身的表现通常并不重要。然而,Stream 是一个为700家公司和超过5亿终端用户提供 feed 和聊天平台的 API 提供商。多年来,我们一直在优化 Cassandra、 PostgreSQL、 Redis 等等,但最终,我们达到了所使用语言的极限。Python 是一种很棒的语言,但是对于序列化/反序列化、排序和聚合等用例来说,它的性能相当缓慢。我们经常遇到性能问题,Cassandra 需要1ms 来检索数据,而 Python 需要10ms 来将数据转换为对象。原因 3 – 开发人员的生产力和没有太有创意看看 我如何开始 Go 教程中的一小段 Go 代码。(这是一个很棒的教程,也是学习 Go 的一个很好的起点。)如果您是 Go 新手,那么在阅读那个小代码片段时不会有太多让您感到惊讶的事情。它展示了多个赋值、数据结构、指针、格式和一个内置的 HTTP 库。当我第一次开始编程时,我一直喜欢使用 Python 更高级的功能。Python 允许您在编写代码时获得相当的创意。例如,您可以:Use MetaClasses to self-register classes upon code initialization 在代码初始化时使用元类自寄存器类Swap out True and False 替换掉 True 和 FalseAdd functions to the list of built-in functions 将函数添加到内置函数列表中Overload operators via magic methods 通过魔术方法重载操作符Use functions as properties via the @property decorator 通过@property decorator 将函数用作属性这些功能玩起来很有趣,但是,正如大多数程序员会同意的那样,在阅读别人的作品时,它们通常会使代码更难理解。Go 迫使你坚持基础。这使得阅读任何人的代码并立即了解发生了什么变得非常容易。 注意:当然,它实际上有多“容易”取决于您的用例。如果你想创建一个基本的 CRUD API,我仍然推荐 Django + DRF或 Rails。这些功能玩起来很有趣,但是,正如大多数程序员会同意的那样,在阅读别人的作品时,它们通常会使代码更难理解。Go 迫使你坚持基础。这使得阅读任何人的代码并立即了解发生了什么变得非常容易。 注意:当然,它实际上有多“容易”取决于您的场景。如果你想创建一个基本的 CRUD API,我仍然推荐 Django + DRF或 Rails。原因 4 – 并发和通道作为一门语言,Go 试图让事情变得简单。它没有引入许多新概念。重点是创建一种非常快速且易于使用的简单语言。它唯一具有创新性的领域是 goroutine 和通道。(100% 正确 CSP的概念始于 1977 年,所以这项创新更多是对旧思想的一种新方法。)Goroutines 是 Go 的轻量级线程方法,通道是 goroutines 之间通信的首选方式。Goroutines 的创建非常便宜,并且只需要几 KB 的额外内存。因为 Goroutine 非常轻量,所以有可能同时运行数百甚至数千个。您可以使用通道在 goroutine 之间进行通信。Go 运行时处理所有复杂性。goroutines 和基于通道的并发方法使得使用所有可用的 CPU 内核和处理并发 IO 变得非常容易——所有这些都不会使开发复杂化。与 Python/Java 相比,在 goroutine 上运行函数需要最少的样例代码。您只需在函数调用前加上关键字“go”:https://tour.golang.org/concurrency/1 Go 的并发方法很容易使用。与 Node 相比,这是一种有趣的方法,开发人员必须密切关注异步代码的处理方式。Go 中并发的另一个重要方面是 竞争检测器。这样可以很容易地确定异步代码中是否存在任何竞争条件。以下是开始使用 Go 和频道的一些很好的资源:https://gobyexample.com/channelshttps://tour.golang.org/concurrency/2http://guzalexander.com/2013/12/06/golang-channels-tutorial.htmlhttps://www.golang-book.com/books/intro/10https://www.goinggo.net/2014/02/the-nature-of-channels-in-go.htmlGoroutines vs Green threads原因 5 – 快速编译时间我们目前用 Go 编写的最大的微服务编译需要 4 秒。与以编译速度慢而闻名的 Java 和 C++ 等语言相比,Go 的快速编译时间是一项重大的生产力胜利。我喜欢剑术,但在我还记得代码应该做什么的同时完成事情会更好:理由 6 - 团队建设的能力首先,让我们从显而易见的开始:与 C++ 和 Java 等旧语言相比,Go 开发人员的数量并不多。根据 StackOverflow的数据, 38% 的开发人员知道 Java, 19.3%的 人知道 C++,只有 4.6%的 人知道 Go。 GitHub 数据 显示了 类似的趋势:Go 比 Erlang、Scala 和 Elixir 等语言使用更广泛,但不如 Java 和 C++ 流行。幸运的是,Go 是一种非常简单易学的语言。它提供了您需要的基本功能,仅此而已。它引入的新概念是“延迟”声明和内置的并发管理与“goroutines”和通道。(对于纯粹主义者来说:Go 并不是第一种实现这些概念的语言,只是第一种使它们流行起来的语言。)任何加入团队的 Python、Elixir、C++、Scala 或 Java 开发人员都可以在一个月内在 Go 上上手,因为它的简单性。与许多其他语言相比,我们发现组建 Go 开发人员团队更容易。如果您在生态系统中招聘人员, 这是一项重要的优势。理由 7 – 强大的生态系统对于我们这样规模的团队(大约20人)来说,生态系统很重要。如果你不得不彻底改造每一个小功能,你就不能为你的客户创造价值。Go 对我们使用的工具有很好的支持。实体库已经可用于 Redis、RabbitMQ、PostgreSQL、模板解析、任务调度、表达式解析和 RocksDB。与 Rust 或 Elixir 等其他较新的语言相比,Go 的生态系统是一个重大胜利。它当然不如 Java、Python 或 Node 之类的语言好,但它很可靠,而且对于许多基本需求,你会发现已经有高质量的包可用。原因 8 – Gofmt,强制代码格式化让我们从什么是 Gofmt 开始?不,这不是一个发誓的话。Gofmt 是一个很棒的命令行实用程序,内置在 Go 编译器中,用于格式化代码。就功能而言,它与 Python 的 autopep8 非常相似。尽管《硅谷》的节目以其他方式描绘,但我们大多数人并不真正喜欢争论制表符与空格。格式的一致性很重要,但实际的格式标准并不那么重要。Gofmt 通过使用一种正式的方式来格式化您的代码来避免所有这些讨论。原因 9 – gRPC 和协议缓冲区Go 对 Protocol Buffers 和 gRPC 有一流的支持。这两个工具非常适合构建需要通过 RPC 进行通信的微服务。您需要做的就是编写一个清单,定义可以进行的 RPC 调用以及它们采用的参数。然后从这个清单中自动生成服务器和客户端代码。生成的代码速度快,网络占用空间小,易于使用。从同一个清单中,您甚至可以为许多不同的语言生成客户端代码,例如 C++、Java、Python 和 Ruby。因此,内部流量不再有模棱两可的 REST 端点,而且您每次都必须编写几乎相同的客户端和服务器代码。缺点 1 – 缺乏框架Go 没有像 Rails 用于 Ruby、Django 用于 Python 或 Laravel 用于 PHP 那样的单一主导框架。这是 Go 社区内激烈争论的话题,因为许多人主张你不应该一开始就使用框架。我完全同意这对于某些用例是正确的。但是,如果有人想构建一个简单的 CRUD API,他们将更容易使用 Django/DJRF、Rails Laravel 或 Phoenix。 更新: 正如评论所指出的,有几个项目为 Go 提供了框架。 Revel , Iris , Echo , Macaron 和 Buffalo 似乎是主要的竞争者。对于 Stream 的用例,我们更喜欢不使用框架。然而,对于许多希望提供简单 CRUD API 的新项目来说,缺乏主导框架将是一个严重的劣势。缺点 2 – 错误处理Go 通过简单地从函数返回错误并期望调用代码来处理错误(或将其返回到调用堆栈)来处理错误。虽然这种方法有效,但很容易失去问题的范围,以确保您可以向用户提供有意义的错误。错误包 通过允许您向错误添加上下文和堆栈跟踪来解决此问题。 另一个问题是很容易忘记处理错误。像 errcheck 和 megacheck 这样的静态分析工具可以方便地避免犯这些错误。虽然这些变通办法效果很好,但感觉不太对劲。您希望该语言支持正确的错误处理。劣势3——包管理更新:自写这篇文章以来,Go 的包管理已经取得了长足的进步。 Go 模块 是一个有效的解决方案,我看到的唯一问题是它们破坏了一些静态分析工具,如 errcheck。这是一个使用 Go modules学习使用 Go 的教程 。 Go 的包管理绝不是完美的。默认情况下,它无法指定特定版本的依赖项,也无法创建可重现的构建。Python、Node 和 Ruby 都有更好的包管理系统。但是,使用正确的工具,Go 的包管理工作得很好。您可以使用 Dep 来管理您的依赖项,以允许指定和固定版本。除此之外,我们还贡献了一个名为的开源工具 VirtualGo ,它可以更轻松地处理用 Go 编写的多个项目。结论Go 是一种非常高性能的语言,对并发有很好的支持。它几乎与 C++ 和 Java 等语言一样快。虽然与 Python 或 Ruby 相比,使用 Go 构建东西确实需要更多时间,但您将节省大量用于优化代码的时间。我们在 Stream有一个小型开发团队, 为超过 5 亿最终用户 提供动力和 聊天。Go 结合了 强大的生态系统、 新开发人员的 轻松入门、快速的性能、 对并发的 可靠支持和高效的编程环境 ,使其成为一个不错的选择。 **Stream 仍然在我们的仪表板、站点和机器学习中利用 Python 来提供 个性化的订阅源. 我们不会很快与 Python 说再见,但今后所有性能密集型代码都将使用 Go 编写。我们新的 聊天 API 也完全用 Go 编写。**如果您想了解有关 Go 的更多信息,请查看下面列出的博客文章。原文链接:https://blog.csdn.net/inthat/article/details/124994033
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签