我需要在表格样式矩阵中对XYZ坐标进行排序和排列,以导出为.csv文件。
在用户Michael0x2a的帮助下,我设法或多或少地做到了。我现在的问题是,如果我重复了X和Y,它将为Z返回0。
def find_x_and_y(array):
"""Step 1: Get unique x and y coordinates and the width and height of the matrix"""
x = sorted(list(set([i[0] for i in array])))
y = sorted(list([i[1] for i in array]))
height = len(x) + 1
width = len(y) + 1
return x, y, width, height
def construct_initial_matrix(array):
"""Step 2: Make the initial matrix (filled with zeros)"""
x, y, width, height = find_x_and_y(array)
matrix = []
for i in range(height):
matrix.append([0] * width)
return matrix
def add_edging(array, matrix):
"""Step 3: Add the x and y coordinates to the edges"""
x, y, width, height = find_x_and_y(array)
for coord, position in zip(x, range(1, height)):
matrix[position][0] = coord
for coord, position in zip(y, range(1, width)):
matrix[0][position] = coord
return matrix
def add_z_coordinates(array, matrix):
"""Step 4: Map the coordinates in the array to the position in the matrix"""
x, y, width, height = find_x_and_y(array)
x_to_pos = dict(zip(x, range(1, height)))
y_to_pos = dict(zip(y, range(1, width)))
for x, y, z in array:
matrix[x_to_pos[x]][y_to_pos[y]] = z
return matrix
def make_csv(matrix):
"""Step 5: Printing"""
return '\n'.join(', '.join(str(i) for i in row) for row in matrix)
def main(array):
matrix = construct_initial_matrix(array)
matrix = add_edging(array, matrix)
matrix = add_z_coordinates(array, matrix)
print make_csv(matrix)
如果我运行下面的示例,它将返回
example = [[1, 1, 20], [1, 1, 11], [2, 3, 12.1], [2, 5, 13], [5,4,10], [3,6,15]]
main(example)
0, 1, 1, 3, 4, 5, 6
1, 0, 11, 0, 0, 0, 0
2, 0, 0, 12.1, 0, 13, 0
3, 0, 0, 0, 0, 0, 15
5, 0, 0, 0, 10, 0, 0
因此列标题是y值,行标题是x值。
对于第一组[1,1,20]它返回1,1,0因为第二组[1,1,11]具有相同的x和y值。
最终结果应为:
0, 1, 1, 3, 4, 5, 6
1, 20, 11, 0, 0, 0, 0
2, 0, 0, 12.1, 0, 13, 0
3, 0, 0, 0, 0, 0, 15
5, 0, 0, 0, 10, 0, 0
我认为这与此功能有关:
x_to_pos = dict(zip(x, range(1, height)))
y_to_pos = dict(zip(y, range(1, width)))
任何人都可以帮我解决这个问题吗?
非常感谢
旧金山
答案 0 :(得分:0)
这是一个建议。它使用sorted
上的range
函数和key
参数来获取稍后对x
和y
进行排序所需的索引(问题中的更多详细信息{ {3}})。这会自动处理重复值。
example = [[1, 1, 20], [1, 1, 11], [2, 3, 12.1], [2, 5, 13], [5,4,10], [3,6,15]]
x = [el[0] for el in example]
y = [el[1] for el in example]
z = [el[2] for el in example]
# indices for x,y to get them in sorted order later
# duplicates in both dimensions are preserved
x_idx = sorted(range(len(x)), key=lambda k:x[k])
y_idx = sorted(range(len(y)), key=lambda k:y[k])
# initialize A with 0
A = [[0 for _ in range(len(y)+1)] for _ in range(len(x)+1)]
# and fill it with values
for k, val in enumerate(z):
A[x_idx[k]+1][y_idx[k]+1] = val
A[k+1][0] = x[x_idx[k]]
A[0][k+1] = y[y_idx[k]]
但是,此脚本的结果不是(还)。 A
最终看起来像这样:
[[0, 1, 1, 3, 4, 5, 6],
[1, 20, 0, 0, 0, 0, 0],
[1, 0, 11, 0, 0, 0, 0],
[2, 0, 0, 12.1, 0, 0, 0],
[2, 0, 0, 0, 0, 13, 0],
[3, 0, 0, 0, 0, 0, 15],
[5, 0, 0, 0, 10, 0, 0]]
请注意,重复值1
不仅创建了新列,还创建了新行。
假设:仅合并具有相同索引的行。这可以使用itertools
groupby函数和zip + sum来完成,通过简单地将它们逐列相加来“合并”行。第一列(行索引)必须切片:
AA = []
for row_index, rows_to_be_merged in itertools.groupby(A, lambda x: x[0]):
AA.append([row_index] +
[sum(rows) for rows in zip(*rows_to_be_merged)][1:])
结果列表AA
如下所示:
[[0, 1, 1, 3, 4, 5, 6],
[1, 20, 11, 0, 0, 0, 0],
[2, 0, 0, 12.1, 0, 13, 0],
[3, 0, 0, 0, 0, 0, 15],
[5, 0, 0, 0, 10, 0, 0]]