如何在2D数组中切换行和列?

时间:2017-04-02 02:07:57

标签: python arrays algorithm multidimensional-array pascals-triangle

我正在开发一个代码,它将为3D打印创建一个可视化的Sierpinski三角形,为了使其工作,我必须使用Pascal三角形算法来创建一个数组,这样我就可以用来告诉我的算法创建我的三角形,不要放三角形。

无论如何问题是,我排列三角形的代码按列而不是像Pascal算法那样按行创建三角形,所以我只是想通过重新安排Pascal数组的子程序来快速修复。由于我不确定如何避免// Floor made out of square tiles. struct Floor { private var computedPerimeter: Int? = nil let size: (x: Int, y: Int), // How many tiles in the floor tilePerimeter: Int // Calculate entire floor's perimeter based on tile quantity and perimeter: var perimeter: Int { mutating get { if computedPerimeter == nil { let t4th = self.tilePerimeter / 4, // Tile width / length sx = self.size.x * t4th, // All X tiles' length sy = self.size.y * t4th // All Y tiles' width computedPerimeter = ((sx * 2) + (sy * 2)) // Perimeter calc } return computedPerimeter! } } }; 错误,我只是难以理解如何操作。

这是为Pascal的三角形创建数组的代码。

TL:DR 我正在尝试重新排列一个数组,其中行是列,列是行

index out of range

这是打印数组的输出。我只希望行为列和列为行

def pascal(n):
    """Prints out n rows of Pascal's triangle."""
    row = [1]
    global array
    array = [[0 for x in range(int(n))] for y in range(int(n))]
    array[0]=row
    k = [0]
    for x in range(int(max(n,0)-1)):
       row=[l+r for l,r in zip(row+k,k+row)]
       array[x+1]=row
    return 1

如果您对该项目感到好奇,那么这是完整的代码,但它需要[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1], [1, 6, 15, 20, 15, 6, 1], [1, 7, 21, 35, 35, 21, 7, 1]] 来制作模型。

rhinoscriptsyntax

4 个答案:

答案 0 :(得分:4)

对于转置方阵,简单的解决方案是

transposed_array = zip(*array)

此方法不适用于三角形数据,因为zip在行长度不等时不插入填充。但是itertools.izip_longest确实如此:

import itertools
transposed_array = itertools.izip_longest(*array)

默认情况下,izip_longest会填充None,因此您会得到以下结果:

[(1, 1, 1, 1, 1),
 (None, 1, 2, 3, 4),
 (None, None, 1, 3, 6),
 (None, None, None, 1, 4),
 (None, None, None, None, 1)]

如果您愿意,可以使用列表解析删除None条目:

no_nones = [[item for item in row if item is not None] for row in transposed_array]

让你:

[[1, 1, 1, 1, 1],
 [1, 2, 3, 4],
 [1, 3, 6],
 [1, 4],
 [1]]

如果您希望使用0(或其他任何内容)填充,请将其指定为fillvalue的{​​{1}}关键字参数; e.g。

itertools.izip_longest

返回

list(itertools.izip_longest(*array, fillvalue=0))

我在这里假设一个元组列表适用于您的目的。如果你需要内部变为可变,你可以通过列表理解得到它,例如:

[(1, 1, 1, 1, 1),
 (0, 1, 2, 3, 4),
 (0, 0, 1, 3, 6),
 (0, 0, 0, 1, 4),
 (0, 0, 0, 0, 1)]

答案 1 :(得分:1)

你可能想要这样的东西:

def pascal(n):
    a = [[int(i==0) for j in range(n)] for i in range(n)]
    for i in range(n):
        for j in range(1, 1+i):
            a[j][i] = a[j][i-1] + a[j-1][i-1]

    for line in a: print(line)

pascal(7)

打印:

[1, 1, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 5, 6]
[0, 0, 1, 3, 6, 10, 15]
[0, 0, 0, 1, 4, 10, 20]
[0, 0, 0, 0, 1, 5, 15]
[0, 0, 0, 0, 0, 1, 6]
[0, 0, 0, 0, 0, 0, 1]

答案 2 :(得分:1)

你可以如图所示。它的工作原理是首先使数组成方形,以便所有行具有相同数量的元素。然后使用内置的zip()函数转置行和列,最后删除它最初添加的元素。

另请注意,我删除了全局变量array的使用。最好避免使用全局变量。

from pprint import pprint

def pascal(n):
    """Creates n rows of Pascal's triangle."""
    array = [None for y in range(n)]

    row = [1]
    array[0] = row
    k = [0]
    for x in range(max(n, 0)-1):
       row = [l+r for l,r in zip(row+k, k+row)]
       array[x+1] = row

    return array

def transpose(array):
    array = array[:]  # make copy to avoid changing original
    n = len(array)
    for i, row in enumerate(array):
        array[i] = row + [None for _ in range(n - len(row))]

    array = zip(*array)

    for i, row in enumerate(array):
        array[i] = [elem for elem in row if elem is not None]

    return array

array = pascal(8)
array = transpose(array)
pprint(array)

输出:

[[1, 1, 1, 1, 1, 1, 1, 1],
 [1, 2, 3, 4, 5, 6, 7],
 [1, 3, 6, 10, 15, 21],
 [1, 4, 10, 20, 35],
 [1, 5, 15, 35],
 [1, 6, 21],
 [1, 7],
 [1]]

答案 3 :(得分:0)

您可以在将每行的长度与最大行匹配并用零填充之后转置行和列。

工作代码如下。来自this SO postnumpy_fillna函数。

import numpy as np
x = [[1],
 [1, 1],
 [1, 2, 1],
 [1, 3, 3, 1],
 [1, 4, 6, 4, 1],
 [1, 5, 10, 10, 5, 1],
 [1, 6, 15, 20, 15, 6, 1],
 [1, 7, 21, 35, 35, 21, 7, 1]]

a = np.array(x)

def numpy_fillna(data):
    # Get lengths of each row of data
    lens = np.array([len(i) for i in data])

    # Mask of valid places in each row
    mask = np.arange(lens.max()) < lens[:,None]

    # Setup output array and put elements from data into masked positions
    out = np.zeros(mask.shape, dtype=data.dtype)
    out[mask] = np.concatenate(data)
    return out

结果

>>> numpy_fillna(a).T
array([[1, 1, 1, 1, 1, 1, 1, 1],
       [0, 1, 2, 3, 4, 5, 6, 7],
       [0, 0, 1, 3, 6, 10, 15, 21],
       [0, 0, 0, 1, 4, 10, 20, 35],
       [0, 0, 0, 0, 1, 5, 15, 35],
       [0, 0, 0, 0, 0, 1, 6, 21],
       [0, 0, 0, 0, 0, 0, 1, 7],
       [0, 0, 0, 0, 0, 0, 0, 1]], dtype=object)
>>>