2015-08-16 21 views
18

Chức năng Tôi đang tìm kiếm một cái gì đó trông như thế này:NumPy: Fix mảng với hàng có độ dài khác nhau bằng cách điền vào các yếu tố trống với số không

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

result = fix(data) 
print result 

[[ 1. 2. 3. 4.] 
[ 2. 3. 1. 0.] 
[ 5. 5. 5. 5.] 
[ 1. 1. 0. 0.]] 

Những mảng dữ liệu tôi đang làm việc với là thực sự lớn vì vậy tôi sẽ thực sự đánh giá cao giải pháp hiệu quả nhất.

Chỉnh sửa: Dữ liệu được đọc từ đĩa dưới dạng danh sách các danh sách python.

+0

chỉ cần thêm các kiểu dữ liệu để gọi hàm mảng, 'np.array (..., dtype = np.float64) np.array (..., dtype = np.float64)', hoặc sử dụng 'loadtxt',' savetxt' từ numpy. – zeroth

+1

@zeroth Tôi đã thử điều đó và nhận ValueError: thiết lập một phần tử mảng với một chuỗi. Bạn có thể giải thích thêm? – user2909415

+1

Có khả năng là Ma trận thưa thớt với hầu hết các mục nhập bằng không? Nó có thể phù hợp trong bộ nhớ như một ma trận dày đặc? –

Trả lời

13

Đây có thể là một cách tiếp cận -

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 

mẫu đầu vào, đầu ra -

In [222]: # Input object dtype array 
    ...: data = np.array([[1, 2, 3, 4], 
    ...:     [2, 3, 1], 
    ...:     [5, 5, 5, 5, 8 ,9 ,5], 
    ...:     [1, 1]]) 

In [223]: numpy_fillna(data) 
Out[223]: 
array([[1, 2, 3, 4, 0, 0, 0], 
     [2, 3, 1, 0, 0, 0, 0], 
     [5, 5, 5, 5, 8, 9, 5], 
     [1, 1, 0, 0, 0, 0, 0]], dtype=object) 
+0

Tôi nghĩ 'lens.size' phải là' lens.max() '- trong câu trả lời của bạn là bằng nhau để tạo ra một ma trận vuông. Nhưng hãy thử với một hàng rách rưới dài hơn số hàng và bạn sẽ gặp lỗi. –

+0

Câu trả lời được chấp nhận gần như chính xác. Tôi cho rằng đó là một sự giám sát, nhưng như sau: # Mặt nạ của các địa điểm hợp lệ trong mỗi hàng mặt nạ = np.arange (lens.size)

4

Điều này sẽ tốt đẹp nếu ở một số cách được vector hóa, nhưng Im vẫn là NOOB, vì vậy tất cả những gì tôi có thể nghĩ ngay bây giờ!

import numpy as np,numba as nb 
a=np.array([[1, 2, 3, 4], 
       [2, 3, 1], 
       [5, 5, 5, 5,5], 
       [1, 1]]) 
@nb.jit() 
def f(a): 
    l=len(max(a,key=len)) 
    a0=np.empty(a.shape+(l,)) 
    for n,i in enumerate(a.flat): 
     a0[n]=np.pad(i,(0,l-len(i)),mode='constant') 
    a=a0 
    return a 

print(f(a)) 
11

Bạn có thể sử dụng pandas thay vì NumPy:

In [1]: import pandas as pd 

In [2]: df = pd.DataFrame([[1, 2, 3, 4], 
    ...:     [2, 3, 1], 
    ...:     [5, 5, 5, 5], 
    ...:     [1, 1]], dtype=float) 


In [3]: df.fillna(0.0).values 
Out[3]: 
array([[ 1., 2., 3., 4.], 
     [ 2., 3., 1., 0.], 
     [ 5., 5., 5., 5.], 
     [ 1., 1., 0., 0.]]) 
+0

Dường như không hoạt động với các mức lồng sâu hơn, mặc dù :( –

4

sử dụng np.pad().

In [62]: arr 
Out[62]: 
[array([0]), 
array([83, 74]), 
array([87, 61, 23]), 
array([71, 3, 81, 77]), 
array([20, 44, 20, 53, 60]), 
array([54, 36, 74, 35, 49, 54]), 
array([11, 36, 0, 98, 29, 87, 21]), 
array([ 1, 22, 62, 51, 45, 40, 36, 86]), 
array([ 7, 22, 83, 58, 43, 59, 45, 81, 92]), 
array([68, 78, 70, 67, 77, 64, 58, 88, 13, 56])] 

In [63]: max_len = np.max([len(a) for a in arr]) 

In [64]: np.asarray([np.pad(a, (0, max_len - len(a)), 'constant', constant_values=0) for a in arr]) 
Out[64]: 
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
     [83, 74, 0, 0, 0, 0, 0, 0, 0, 0], 
     [87, 61, 23, 0, 0, 0, 0, 0, 0, 0], 
     [71, 3, 81, 77, 0, 0, 0, 0, 0, 0], 
     [20, 44, 20, 53, 60, 0, 0, 0, 0, 0], 
     [54, 36, 74, 35, 49, 54, 0, 0, 0, 0], 
     [11, 36, 0, 98, 29, 87, 21, 0, 0, 0], 
     [ 1, 22, 62, 51, 45, 40, 36, 86, 0, 0], 
     [ 7, 22, 83, 58, 43, 59, 45, 81, 92, 0], 
     [68, 78, 70, 67, 77, 64, 58, 88, 13, 56]]) 
Các vấn đề liên quan