我知道c++的一些基础知识,但我是python的初学者。在
我有一段工作代码(见下文),我想添加一个约束来格式化它的输出,但我不知道怎么做。。。在
让我先解释一下这个程序的作用:
我有一个输入文件colors.csv
,其中包含一个颜色列表,一行一个颜色:颜色由它们的名称和色度坐标X、Y和Z定义,看起来是这样的:
Colorname, X1, Y1, Z1
Colorname2, X2, Y2, Z2
...etc.
给定包含在另一个输入文件targets.csv
中的任何XYZ坐标列表,程序将在输出文件output.txt
中给我一个解决方案列表
这个解的计算方法是先用tetgen对点云进行三角剖分,然后在四面体中对点的重心坐标进行计算(但这里解释一切都无关紧要…)
解决方案的形式如下:
^{pr2}$总是只有4个名字和相关的密度。在
它看起来像这样:
122 ,PINKwA,0.202566115168,GB,0.718785775317,PINK,0.0647284446787,TUwA,0.0139196648363
123 ,PINKwA,0.200786239192,GB,0.723766147717,PINK,0.0673550497794,TUwA,0.00809256331169
124 ,PINKwA,0.19900636349,GB,0.72874651935,PINK,0.0699816544755,TUwA,0.00226546268446
125 ,OR0A,0.00155317194109,PINK,0.0716160265958,PINKwA,0.195962072115,GB,0.730868729348
126 ,OR0A,0.00409427478508,PINK,0.0726192660009,PINKwA,0.192113520109,GB,0.731172939105
127 ,OR0A,0.00663537762906,PINK,0.073622505406,PINKwA,0.188264968103,GB,0.731477148862
我现在想做什么?
出于实际原因,我希望我的输出遵循一定的顺序。
我想要一个“优先级列表”来控制name, density
输出的顺序。在
我的实际程序以我不理解的顺序输出颜色名称,但无论如何,我需要这些颜色名称按特定的顺序排列,例如PINK
应该总是第一个PINKwA
第二个,等等
而不是:
127 ,OR0A,0.00663537762906,PINK,0.073622505406,PINKwA,0.188264968103,GB,0.731477148862
我想要
127 ,PINK,0.073622505406,PINKwA,0.188264968103,OR0A,0.00663537762906,GB,0.731477148862
因为我的优先顺序是:
0, PINK
1, PINKwA
2, OR0A
3, GB
我怎样才能简单地将这个函数添加到下面的代码中?有什么想法吗?在
编辑代码(作品…):
import tetgen, geometry
from pprint import pprint
import random, csv
import numpy as np
from pprint import pprint
all_colors = [(name, float(X), float(Y), float(Z))
for name, X, Y, Z in csv.reader(open('colors.csv'))]
priority_list = {name: int(i)
for i, name in csv.reader(open('priority.csv'))}
# background is marked SUPPORT
support_i = [i for i, color in enumerate(all_colors) if color[0] == 'SUPPORT']
if len(support_i)>0:
support = np.array(all_colors[support_i[0]][1:])
del all_colors[support_i[0]]
else:
support = None
tg, hull_i = geometry.tetgen_of_hull([(X,Y,Z) for name, X, Y, Z in all_colors])
colors = [all_colors[i] for i in hull_i]
print ("thrown out: "
+ ", ".join(set(zip(*all_colors)[0]).difference(zip(*colors)[0])))
targets = [(name, float(X), float(Y), float(Z), float(BG))
for name, X, Y, Z, BG in csv.reader(open('targets.csv'))]
for target in targets:
name, X, Y, Z, BG = target
target_point = support + (np.array([X,Y,Z]) - support)/(1-BG)
tet_i, bcoords = geometry.containing_tet(tg, target_point)
output = open('output.txt','a')
if tet_i == None:
output.write(str(target[0]))
output.write('\n')
else:
names = [colors[i][0] for i in tg.tets[tet_i]]
sorted_indices = sorted(enumerate(names), key=lambda (i, name): priority_list[name])
output.write(target[0])
counting = 0
for i, name in sorted(enumerate(names), key=lambda (i, name): priority_list[name]):
output.write(',%s,%s' % (name, bcoords[i]))
counting = counting + 1
if counting > 3:
output.write('\n')
counting = 0
output.close()
首先,您需要在Python代码中直接对优先级列表进行编码:
这将允许您快速检索给定颜色名称的顺序。然后,可以使用
^{pr2}$key
参数对sorted
按优先级对名称进行排序。不过,关键的是,您需要检索的不是排序名称,而是排序名称的索引,就像http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html。在enumerate
内置项用其在原始名称列表中的索引对每个名称进行注释,然后sorted
内置项将根据其在优先级列表中的排名对得到的{bcoords
数组中相应的元素(使用索引值)。在所以,我把你代码中的最后一个块做成这样:
在这里,我更改了文件输出策略,使其更像python,将字符串添加到一起基本上是不可能的,最好创建一个格式字符串并填充变量(也可以在字符串上使用
.format()
来完成这项工作)。另外,您可以多次调用.write()
,它们将继续向文件中写入字节,因此不需要一次创建一个大的长字符串来进行写操作。最后,不需要对'\r\n'
调用str
,因为它已经是一个字符串了。在相关问题 更多 >
编程相关推荐