2012-04-13 37 views
22

Tôi có mã sau đang cố gắng bình thường hóa các giá trị của một mảng m x n (Nó sẽ được sử dụng làm đầu vào cho mạng nơron, trong đó m là số lượng ví dụ đào tạo và n là số tính năng).Sửa đổi nhiều mảng tại chỗ?

Tuy nhiên, khi tôi kiểm tra mảng trong trình thông dịch sau khi tập lệnh chạy, tôi thấy rằng các giá trị không được chuẩn hóa; có nghĩa là, họ vẫn có giá trị ban đầu. Tôi đoán điều này là do việc gán cho biến số array bên trong hàm chỉ được thấy trong hàm.

Làm cách nào để tôi có thể thực hiện việc chuẩn hóa này? Hay tôi phải trả về một mảng mới từ hàm bình thường?

import numpy 

def normalize(array, imin = -1, imax = 1): 
    """I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)""" 

    dmin = array.min() 
    dmax = array.max() 

    array = imin + (imax - imin)*(array - dmin)/(dmax - dmin) 
    print array[0] 


def main(): 

    array = numpy.loadtxt('test.csv', delimiter=',', skiprows=1) 
    for column in array.T: 
     normalize(column) 

    return array 

if __name__ == "__main__": 
    a = main() 

Trả lời

19

Nếu bạn muốn áp dụng các hoạt động toán học để một mảng NumPy tại chỗ, bạn chỉ có thể sử dụng tiêu chuẩn tại chỗ khai thác +=, -=, /=, vv Vì vậy, ví dụ:

>>> def foo(a): 
...  a += 10 
... 
>>> a = numpy.arange(10) 
>>> a 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> foo(a) 
>>> a 
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) 

các tại chỗ phiên bản của các hoạt động này là một chút nhanh hơn để khởi động, đặc biệt là đối với mảng lớn:

>>> def normalize_inplace(array, imin=-1, imax=1): 
...   dmin = array.min() 
...   dmax = array.max() 
...   array -= dmin 
...   array *= imax - imin 
...   array /= dmax - dmin 
...   array += imin 
...  
>>> def normalize_copy(array, imin=-1, imax=1): 
...   dmin = array.min() 
...   dmax = array.max() 
...   return imin + (imax - imin) * (array - dmin)/(dmax - dmin) 
... 
>>> a = numpy.arange(10000, dtype='f') 
>>> %timeit normalize_inplace(a) 
10000 loops, best of 3: 144 us per loop 
>>> %timeit normalize_copy(a) 
10000 loops, best of 3: 146 us per loop 
>>> a = numpy.arange(1000000, dtype='f') 
>>> %timeit normalize_inplace(a) 
100 loops, best of 3: 12.8 ms per loop 
>>> %timeit normalize_copy(a) 
100 loops, best of 3: 16.4 ms per loop 
+0

thời gian '% timeit' là gì? Điều đó có vẻ thú vị, là nó được xây dựng trong? – User

+0

Phiên bản tôi sử dụng ở đây chỉ được tích hợp trong [ipython] (http://ipython.org/). Nhưng nó dựa trên hàm 'timeit' trong mô-đun [' timeit'] (http://docs.python.org/library/timeit.html#module-timeit). – senderle

+0

Ah cuối cùng cũng nhìn vào ipython. Buồn cười tôi đã luôn luôn liên kết nó với ironpython, nhầm lẫn bây giờ tôi nhìn thấy. – User

3
def normalize(array, imin = -1, imax = 1): 
    """I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)""" 

    dmin = array.min() 
    dmax = array.max() 


    array -= dmin; 
    array *= (imax - imin) 
    array /= (dmax-dmin) 
    array += imin 

    print array[0] 
+0

Hiệu suất-khôn ngoan là có bất kỳ vấn đề làm theo cách này? Nó so sánh như thế nào để tạo một mảng mới? – User

+0

Ý tôi là, vì điều đó bạn phải chuẩn bị. Nó phụ thuộc vào kích thước của mảng. Đối với các vấn đề nhỏ, tôi chắc chắn sẽ tạo mảng mới. – ely

1

Có một cách hay để làm bình thường tại chỗ khi sử dụng numpy. np.vectorize rất hữu ích khi được kết hợp với hàm lambda khi được áp dụng cho một mảng. Xem ví dụ bên dưới:

import numpy as np 

def normalizeMe(value,vmin,vmax): 

    vnorm = float(value-vmin)/float(vmax-vmin) 

    return vnorm 

imin = 0 
imax = 10 
feature = np.random.randint(10, size=10) 

# Vectorize your function (only need to do it once) 
temp = np.vectorize(lambda val: normalizeMe(val,imin,imax)) 
normfeature = temp(np.asarray(feature)) 

print feature 
print normfeature 

Có thể so sánh hiệu suất với biểu thức máy phát, tuy nhiên có nhiều cách khác để thực hiện việc này.

%%timeit 
temp = np.vectorize(lambda val: normalizeMe(val,imin,imax)) 
normfeature1 = temp(np.asarray(feature)) 
10000 loops, best of 3: 25.1 µs per loop 


%%timeit 
normfeature2 = [i for i in (normalizeMe(val,imin,imax) for val in feature)] 
100000 loops, best of 3: 9.69 µs per loop 

%%timeit 
normalize(np.asarray(feature)) 
100000 loops, best of 3: 12.7 µs per loop 

Vì vậy, vectorize chắc chắn không phải là nhanh nhất, nhưng có thể thuận tiện trong trường hợp hiệu suất không quan trọng.

+0

Nó thực hiện công việc, nhưng nó rất chậm vì nó được thực hiện như một vòng lặp, theo tài liệu. – Michael

+0

Có điểm chuẩn nào cho loại điều này không? Bạn hy vọng rằng vectorize có thể giúp nó đi nhanh hơn nhiều. – user48956

0

Đây là một thủ thuật mà nó là hơi tổng quát hơn câu trả lời hữu ích khác tại đây:

def normalize(array, imin = -1, imax = 1): 
    """I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)""" 

    dmin = array.min() 
    dmax = array.max() 

    array[...] = imin + (imax - imin)*(array - dmin)/(dmax - dmin) 

Ở đây chúng ta đang gán giá trị cho quan điểm array[...] hơn là gán các giá trị cho một số biến cục bộ mới trong phạm vi của hàm.

x = np.arange(5, dtype='float') 
print x 
normalize(x) 
print x 

>>> [0. 1. 2. 3. 4.] 
>>> [-1. -0.5 0. 0.5 1. ] 
Các vấn đề liên quan