这段代码在 Python 里能怎么改写成效率更高的吗,听说 for 循环比较慢
xs = []
ys = []
zs = []
for data in ls:
_x, _y, _z = data
xs.append(_x)
ys.append(_y)
zs.append(_z)
用 numpy
xs = ls[:,0]
ys = ls[:,1]
zs = ls[:,2]
ls = numpy.array(ls)
等待 python3.11 版本,听说有一倍速度的提升🐶
不是数字呃,numpy 能处理非数字吗
不太清楚具体需求,也许可以让 xs,ys,zs 变成迭代器而不是 list ?
不考虑数组转 np array 的这个开销的话,1 楼的 numpy 确实非常快:
Using numpy: 0.00000000s
Using append: 0.36167359s
加上转 np 的开销嘛,就不一样了:
Using numpy: 1.69339228s
Using append: 0.37969041s
其实 append 还是挺快的,比非常 Pythonic 的*zip 的方法要快挺多了:
Using *zip: 1.30143762s
Using append: 0.39510083s
参考:
stackoverflow.com/questions/8081545/how-to-convert-list-of-tuples-to-multiple-lists
zip 怎么样
for 循环不知道怎么去掉,但是有一个提速的方法,list 初始化的时候带上长度
xs = [None] * len(data)
对于比较大的 list,可以快那么几十毫秒。。
用列表推导
xs=[data[0] for data in ls]
ys=[data[1] for data in ls]
zs=[data[2] for data in ls]
用 map 运算
xs = map(lambda data: data[0], ls)
ys = map(lambda data: data[1], ls)
zs = map(lambda data: data[2], ls)
你这把一个循环变成了三个, 应该只会更慢吧
O(n)了还优化个啥
不知道怎么优化,不过代码可以精简一下
for _x, _y, _z in ls:
xs.append(_x)
ys.append(_y)
zs.append(_z)
C++程序员的思路:预先分配下内存防止移动?
你要全部遍历一遍,这个算法已经 O(n),除了直接提速 for 和 append,可以用另外一种思路,就是看你的 xs,ys,zs 的用处,用 yield 把它改成生成器,类似 python2 里 range 到 xrange 的改变。
如果 ls 不变,进一步的优化可以加缓存,用 JSON 存到本地,第二次直接读取 JSON,虽然本身并没有优化到算法。
因为这个操作在 numpy 里面是 constant 的。。通过数据结构实现的。这也就是为什么你把 list 转成 np 的时间非常高的原因。当然了,你也可以试试看把处理好的 xs ys zs 再转成 list,还是很费时间。
np 本身的 dataframe 非常复杂也非常大
其实是一个 90 度旋转二维数组的过程,用 Python 的内置函数实现应该会更快,因为毕竟底层是 C 。
可以先 rotated = list(zip(*ls[::])) 旋转一下二维数组,再 xs.extend(rotated) .
跑起来大概提高了一倍的速度
imgur.com/e602lpH
Python 的优化就是有些反常识,3 个循环不一定比 1 个循环慢,具体还是看解释器怎么跑
预分配内存在 Python 优化中通常效果不佳,因为通常不是主要因素
如果 ls 足够长的话,比如 ls=[[i, i+1, i+2] for i in range(1, 98, 3)],那么这个版本可能更快一些,
flat = list(itertools.chain.from_iterable(ls))
xs = flat[::3]
ys = flat[1::3]
zs = flat[2::3]
好吧,#17 我服了
我测了一下,zip 稍快一些
blob: imgur.com/0782fae0-e12e-46fe-a6ea-0db5e1e39c72
同意,你的版本更快,
In [101]: def t1(ls):
...: flat = list(itertools.chain.from_iterable(ls))
...: xs = flat[::3]
...: ys = flat[1::3]
...: zs = flat[2::3]
...: return xs, ys, zs
...:
In [102]: def t2(ls):
...: xs, ys, zs =list(zip(*ls))
...: return list(xs), list(ys), list(zs)
In [113]: ls=[[i, i+1, i+2] for i in range(1, 98, 3)]
In [114]: %timeit t1(ls)
4.26 µs ± 17.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [115]: %timeit t2(ls)
3.2 µs ± 19.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
其实省掉 extend 过程,直接返回数组的话,还能再提高点性能
🤝 其实大家思路都差不多,python 要提高效率的话,应该尽可能的使用内置函数
对,就是这个道理,内置函数底层执行更快 🤝
#19 学习了。
#19 楼 一行代码开启新世界
def func4(ls):
xs = list(islice(chain.from_iterable(ls), 0, None, 3))
ys = list(islice(chain.from_iterable(ls), 1, None, 3))
zs = list(islice(chain.from_iterable(ls), 2, None, 3))
def func5(ls):
xs = list(compress(chain.from_iterable(ls), cycle([1, 0, 0])))
ys = list(compress(chain.from_iterable(ls), cycle([0, 1, 0])))
zs = list(compress(chain.from_iterable(ls), cycle([0, 0, 1])))
itertools 里的内置函数速度都还可以
ls[::] 是干嘛?我怎么看不懂啊,求教,另外为什么我测的是列表推导式更快一点,数量级越大越明显
另外,只有在 data=[(x,y,z),(x2,y2,z2,...)] 为元祖 zip 才会有明显速度优势,
data[(x,y,z),(x2,y2,z2,...)] range(100000)
for: spend_time:0.03163599967956543
列表推导式:spend_time:0.012620925903320312
zip: spend_time:0.0060007572174072266
data[(x,y,z),(x2,y2,z2,...)] range(100000)
for: spend_time:0.03195595741271973
列表推导式:spend_time:0.012039899826049805
zip: spend_time:0.016546964645385742
xs, ys, zs = zip(*ls)
举个例子,我实现了一个过滤出字符串中所有数字的功能,函数名为filter_number,我想要附加到 str 对象上,这样调用函数可以写成"abc123abc".filter_…
我刚出社会的时候,是用的破解的,我感觉用着还不错.公司项目和自己的个人项目都是用破解插件用的,显示 2099 年的那种. 工作几年后,就开始使用学生邮箱申请一年试用.发现和破解…
一直感觉电脑是根据人脑的特征做出来的,那计算机最基本的总线,在人身上存在吗?人身上这么多外围配件,数据交换类似电脑的总线吗?如果有,做一个外部的“总线控制器”能不能接管外部配件…