2012-07-30 24 views
5

2d-ndarray'ı 2d-ndarray ile eşleştiren bir işlev yazmaya çalışıyorum. Giriş dizisinin satırları bağımsız olarak işlenebilir ve giriş satırları ile çıkışın satırları arasında 1'den 1'e kadar bir ilişki olmalıdır. Girişin her bir satırı için, sıra için verilen bir siparişin polinom genişlemesi hesaplanmalıdır (örnek için doktora bakınız). Mevcut uygulama çalışmaları; ancak satırlar üzerinde açık bir döngü ve "powerMatrix" içindeki satırların çoğaltılmasını gerektirir. Aynı sonucu numpy.power ile tek bir çağrıyla almak mümkün mü? Btw .: Sonuç satırındaki girişlerin sırası benim için önemli değil.Polinom genişletme için 2d numpy.power

import numpy 
def polynomialFeatures(x, order): 
    """ Generate polynomial features of given order for data x. 

    For each row of ndarray x, the polynomial expansions are computed, i.e 
    for row [x1, x2] and order 2, the following row of the result matrix is 
    computed: [1, x1, x1**2, x2, x1*x2, x1**2*x2, x2**2, x1*x2**2, x1**2*x2**2] 

    Parameters 
    ---------- 
    x : array-like 
     2-D array; for each of its rows, the polynomial features are created 

    order : int 
     The order of the polynomial features 

    Returns 
    ------- 
    out : ndarray 
     2-D array of shape (x.shape[0], (order+1)**x.shape[1]) containing the 
     polynomial features computed for the rows of the array x 

    Examples 
    -------- 
    >>> polynomialFeatures([[1, 2, 3], [-1, -2, -3]], 2) 
    array([[ 1 3 9 2 6 18 4 12 36 1 3 9 2 6 18 4 12 
      36 1 3 9 2 6 18 4 12 36] 
      [ 1 -3 9 -2 6 -18 4 -12 36 -1 3 -9 2 -6 18 -4 12 
      -36 1 -3 9 -2 6 -18 4 -12 36]]) 
    """ 
    x = numpy.asarray(x) 
    # TODO: Avoid duplication of rows 
    powerMatrix = numpy.array([range(order+1)] * x.shape[1]).T 
    # TODO: Avoid explicit loop, and use numpy's broadcasting 
    F = [] 
    for i in range(x.shape[0]): 
     X = numpy.power(x[i], powerMatrix).T 
     F.append(numpy.multiply.reduce(cartesian(X), axis=1)) 

    return numpy.array(F) 

print numpy.all(polynomialFeatures([[1, 2, 3], [-1, -2, -3]], 2) == 
       numpy.array([[1, 3, 9, 2, 6, 18, 4, 12, 36, 1, 
           3, 9, 2, 6, 18, 4, 12, 36, 1, 3, 
           9, 2, 6, 18, 4, 12, 36], 
          [1, -3, 9, -2, 6, -18, 4, -12, 36, -1, 
           3, -9, 2, -6, 18, -4, 12, -36, 1, -3, 
           9, -2, 6, -18, 4, -12, 36]])) 

sayesinde Oca

DÜZENLEME: Eksik işlev kartezyen burada tanımlanır: Using numpy to build an array of all combinations of two arrays temel fikir davanız, boyut 0 içinde (boyut taşımaktır

cevap

3

, satır sayısı) "daha yüksek bir boyuta" yolunun hesaplanmasıyla alakası yoktur ve daha sonra otomatik olarak yayınlanır.

Ben senin cartesian yöntem ne yaptığına emin değilim, ama burada X matris üzerinden indeksleme dizilerini oluşturmak için np.indices kullanan bir çözüm:

import numpy as np 
def polynomial_features(x, order): 
    x = np.asarray(x).T[np.newaxis] 
    n = x.shape[1] 
    power_matrix = np.tile(np.arange(order + 1), (n, 1)).T[..., np.newaxis] 
    X = np.power(x, power_matrix) 
    I = np.indices((order + 1,) * n).reshape((n, (order + 1) ** n)).T 
    F = np.product(np.diagonal(X[I], 0, 1, 2), axis=2) 
    return F.T 
+0

+1. [Benim aptalca bir yorumumu sildim - [1,2,3] 'işlevini yerine [[1,2,3]]' yerine, [elbette aynı derecede aptalca sonuçlar verdi.] – DSM

+0

Teşekkürler iş, bu yaptı :-) – frisbee

+0

Bu gerçekten şık bir çözüm! Bunu kullanmamanız için üzerinde çalıştığım küçük bir projede kullanmak istiyorum: https://github.com/dreamwalkerrr/mledu. (eğer bu uygunsa, bu algoritmayı size bağlayacaktır). Ayrıca, 0’lık güce yükseltilen terimleri hariç tutmanın en iyi yolunun ne olacağını bana bildirir misiniz? – dreamwalker