2016-07-04 21 views
9

Cách nào sâu hơn để đệm một mảng với số không ở cuối?Zero pad numpy array

def pad(A, length): 
    ... 

A = np.array([1,2,3,4,5]) 
pad(A, 8) # expected : [1,2,3,4,5,0,0,0] 

Trong trường hợp sử dụng thực tế của tôi, trên thực tế tôi muốn pad một mảng đến nhiều gần gũi nhất của 1024. Ví dụ: 1342 => 2048, 3000 => 3072

Trả lời

12

numpy.pad với chế độ constant làm những gì bạn cần, nơi chúng ta có thể vượt qua một tuple như là đối số thứ hai để biết bao nhiêu số không để pad trên mỗi kích thước, một (2, 3) ví dụ sẽ pad số không ở phía bên trái và số không ở bên phải:

với A như:

A = np.array([1,2,3,4,5]) 

np.pad(A, (2, 3), 'constant') 
# array([0, 0, 1, 2, 3, 4, 5, 0, 0, 0]) 

Nó cũng có thể pad mảng 2D numPy bằng cách thông qua một tuple của các bộ như chiều rộng đệm, mà tak es định dạng của ((top, bottom), (left, right)):

A = np.array([[1,2],[3,4]]) 

np.pad(A, ((1,2),(2,1)), 'constant') 

#array([[0, 0, 0, 0, 0],   # 1 zero padded to the top 
#  [0, 0, 1, 2, 0],   # 2 zeros padded to the bottom 
#  [0, 0, 3, 4, 0],   # 2 zeros padded to the left 
#  [0, 0, 0, 0, 0],   # 1 zero padded to the right 
#  [0, 0, 0, 0, 0]]) 

Đối với trường hợp của bạn, bạn chỉ định ở phía bên trái là zero và ngay bên pad tính từ một bộ phận mô-đun:

B = np.pad(A, (0, 1024 - len(A)%1024), 'constant') 
B 
# array([1, 2, 3, ..., 0, 0, 0]) 
len(B) 
# 1024 

Đối với một A lớn hơn:

A = np.ones(3000) 
B = np.pad(A, (0, 1024 - len(A)%1024), 'constant') 
B 
# array([ 1., 1., 1., ..., 0., 0., 0.]) 

len(B) 
# 3072 
+0

Cảm ơn! Nó có hoạt động nếu độ dài ban đầu là 3000 không? (sau đó chiều dài đệm phải là 3072) – Basj

+0

Vì độ dài đệm phải ở đây là sự khác biệt giữa '1024' và phần còn lại của mô-đun' len (A) 'chia cho '1024'. Nó nên được dễ dàng để kiểm tra. – Psidom

2

này nên làm việc:

def pad(A, length): 
    arr = np.zeros(length) 
    arr[:len(A)] = A 
    return arr 

bạn thể có thể có được hiệu suất tốt hơn một chút nếu bạn khởi tạo một mảng rỗng (np.empty(length)) và sau đó điền vào A và thứ e zeros riêng biệt, nhưng tôi nghi ngờ rằng các tăng tốc sẽ có giá trị phức tạp mã bổ sung trong hầu hết các trường hợp.

Để có được giá trị cho pad lên đến, tôi nghĩ rằng bạn sẽ có thể chỉ cần sử dụng một cái gì đó giống như divmod:

n, remainder = divmod(len(A), 1024) 
n += bool(remainder) 

Về cơ bản, điều này chỉ hiểu ra bao nhiêu lần năm 1024 chia theo chiều dài của mảng của bạn (và phần còn lại của bộ phận đó là gì). Nếu không còn lại, thì bạn chỉ muốn n * 1024 yếu tố. Nếu còn lại, thì bạn muốn (n + 1) * 1024.

tất cả với nhau:

def pad1024(A): 
    n, remainder = divmod(len(A), 1024) 
    n += bool(remainder) 
    arr = np.zeros(n * 1024) 
    arr[:len(A)] = A 
    return arr   
+0

Cảm ơn! Bất kỳ ý tưởng cho đệm tự động để làm cho chiều dài một bội số của 1024? Tôi đang viết một cái gì đó nhưng nó rất cao không phải là pythonic;) – Basj

+0

@Basj - Chắc chắn, kiểm tra cập nhật của tôi. Tôi đã không kiểm tra nó hoặc bất cứ điều gì, nhưng tôi nghĩ rằng nó sẽ làm việc ... – mgilson

+0

Đây là những gì 'pad' không nhưng với rất nhiều chuông-n-còi (phía trước, sau, trục khác nhau, chế độ điền khác). – hpaulj

1

Bạn cũng có thể sử dụng numpy.pad:

>>> A = np.array([1,2,3,4,5]) 
>>> npad = 8 - len(A) 
>>> np.pad(A, pad_width=npad, mode='constant', constant_values=0)[npad:] 
array([1, 2, 3, 4, 5, 0, 0, 0]) 

Và trong một hàm:

def pad(A, npads): 
    _npads = npads - len(A) 
    return np.pad(A, pad_width=_npads, mode='constant', constant_values=0)[_npads:] 
2

np.pad:

A = np.array([1, 2, 3, 4, 5]) 
A = np.pad(A, (0, length), mode='constant') 

Về trường hợp sử dụng của bạn, số lượng yêu cầu số không đến pad có thể được tính là length = len(A) + 1024 - 1024 % len(A).

2

Để tham khảo sau:

def padarray(A, size): 
    t = size - len(A) 
    return np.pad(A, pad_width=(0, t), mode='constant') 

padarray([1,2,3], 8)  # [1 2 3 0 0 0 0 0]