我觉得这应该很简单,但我一直在寻找一个简洁的解决方案。我提供的代码可以工作,并给出了我期望的输出,但我不觉得它是Pythonic,而且它让我感到不安。
我使用基础数据集中的“griddata”生成了三组坐标:X、Y 和 Z。坐标均匀分布在未知的总面积/形状(不一定是正方形/矩形)上,产生 NaN 结果,我想忽略每个列表的边界。应从“左下角”(在坐标系中)开始遍历列表,穿过 x 轴,沿 y 方向向上移动一格,然后从右向左遍历,然后再继续。行数可以是奇数也可以是偶数。
无论方向如何,对每个点执行的操作都是相同的,并且保证X中存在的每个点都存在于Y和Z中,如下面的代码所示。
数组(列表?)的格式为 DataPoint[行][列]。
k = 0
for i in range(len(x)):
if k % 2 == 0: # cut left to right, then right to left
for j in range(len(x[i])):
if not numpy.isnan(x[i][j]):
file.write(f'X{x[i][j]} Y{y[i][j]} Z{z[i][j]}')
else:
for j in reversed(range(len(x[i]))):
if not numpy.isnan(x[i][j]):
file.write(f'X{x[i][j]} Y{y[i][j]} Z{z[i][j]}')
k += 1
我能想到的一个解决方案是在运行循环之前反转每个列表中的每隔一行。这会节省我几行代码,但从性能的角度来看可能没有意义 - 有人有更好的建议吗?
通过列表的预期路线:
End════<══════╗
╔══════>══════╝
╚══════<══════╗
Start══>══════╝
最佳答案
这是一个变体:
for i, (x_row, y_row, z_row) in enumerate(zip(x, y, z)):
if i % 2:
z_row = reversed(x_row)
y_row = reversed(y_row)
z_row = reversed(z_row)
row_strs = list()
for x_elem, y_elem, z_elem in zip(x_row, y_row, z_row):
if not numpy.isnan(x_elem):
row_strs.append(f"X{x_elem} Y{y_elem} Z{z_elem}")
file.write("".join(row_strs))
注意事项:
没有一种优化方法能够始终比其他优化方法表现得更好。它还取决于代码处理的数据。以下是我在不知道数据是什么样子的情况下能想到的事情的列表:
for index range(len(sequence)):
不是 Python 式的迭代方式。这里使用了foreach习惯用法。如果需要索引,[Python 3.Docs]: Built-in Functions - enumerate(iterable, start=0)可以使用- 由于前面的项目符号,这不再适用,但
reversed(range(n))
与range(n - 1, -1, -1)
相同。不知道后者是否更快,但看起来会更快 - 使用 [Python 3.Docs]: Built-in Functions - zip(*iterables) 一次迭代多个可迭代对象
- 不需要k,已经有i
- 一般来说,在处理文件时,读/写大数倍的数据 block 比读/写小数倍的数据 block 要好(文件通常驻留在磁盘上,并且磁盘操作很慢)。但是,默认情况下会发生缓冲(在 Python、OS 级别),因此这不再是问题,但仍然存在。但与往常一样,这是资源(时间、内存……)之间的权衡。
我选择每行写入文件一次(而不是像原来那样每个元素写入一次)。当然,还有第三种rd可能性,即一次写入所有内容,但我想对于更大的数据集,这不会是最好的解决方案 - 也许,一些优化也可能发生在NumPy级别(因为它处理批量数据的速度比Python代码(迭代)快得多),但我不是我是该领域的专家,也不知道数据是什么样的
关于python - Python 列表中的交替方向 - 更多 Pythonic 解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57733643/