[英]How do I remove the first and last rows and columns from a 2D numpy array?
[英]How do I switch rows and columns in a 2D array?
我正在研究一個代碼,它將為3D打印創建一個可視化的Sierpinski三角形,為了使其工作,我必須使用Pascal三角形算法來創建一個數組,這樣我就可以用來告訴我的算法將創建我的三角形哪里不放三角形。
無論如何問題是,我排列三角形的代碼按列而不是像Pascal算法那樣按行創建三角形,所以我只是嘗試通過重新安排Pascal數組的子程序來快速修復。 我只是難以理解如何做到這一點,因為我不知道如何避免index out of range
錯誤。
這是為Pascal三角形創建數組的代碼。
TL:DR我正在嘗試重新排列一個數組,其中行是列,列是行
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
來制作模型。
import rhinoscriptsyntax as rhino
import math
obj = rhino.GetObject("Select object to transform", preselect=True)
scale = 3
n=math.pow(3,scale)
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
pascal(math.pow(2,scale))
print array
def remakePascal():
pass
my_horizontalVector = [[1,0,0,6],
[0,1,0,0],
[0,0,1,0],
[0,0,0,1]]
my_tsfm = [[1,0,0,0], #identity
[0,1,0,0],
[0,0,1,0],
[0,0,0,1]]
def makeTriangle(scale,obj):
w=1/scale
h=1/scale
tsfm= [[w,0,0,0], #scale about origin
[0,h,0,0],
[0,0,1,0],
[0,0,0,1]]
output= rhino.XformMultiply(my_tsfm,tsfm)
new_obj=rhino.TransformObject(obj,output,copy=True)
return new_obj
def placeObj(i):
my_moveUpVector = [[1,0,0,(3/scale)*i],
[0,1,0,(4/scale)*i],
[0,0,1,0],
[0,0,0,1]]
vector = rhino.XformMultiply(my_tsfm,my_moveUpVector)
return vector
n=0
for i in range(int(math.pow(2,scale))):
if(i>0):
hPlace=rhino.XformMultiply(my_tsfm,my_horizontalVector)
obj = rhino.TransformObject(obj,hPlace)
factor = int(math.pow(2,scale))-n
for j in range(factor):
if():
pass
else:
Vertobj=makeTriangle(scale,obj)
tsfm = rhino.TransformObject(Vertobj,placeObj(j),copy=True)
n=n+1
對於轉置方陣,簡單的解決方案是
transposed_array = zip(*array)
這種方法不適用於三角形數據,因為當行長度不等時, zip
不會插入填充。 但是, itertools.izip_longest確實如此:
import itertools
transposed_array = itertools.izip_longest(*array)
默認情況下, izip_longest
使用None
izip_longest
,因此您可以獲得如下結果:
[(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(或其他任何內容)填充,請將其指定為itertools.izip_longest
的fillvalue
關鍵字參數; 例如
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)]
我在這里假設一個元組列表適用於您的目的。 如果你需要內部變為可變,你可以通過列表理解得到它,例如:
list_of_lists = [list(row) for row in transposed_array]
你可能想要這樣的東西:
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]
你可以這樣做。 它的工作原理是首先使數組成方形,以便所有行具有相同數量的元素。 然后使用內置的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]]
在將每行的長度與最大行匹配並用零填充后,可以轉置行和列。
工作代碼如下。 numpy_fillna
函數源自此SO帖子 。
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)
>>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.