2017-05-04 78 views
2

我很難與以下。我有一個叫做p的數據幀N x D,有一些丟失(NAN)值。我有另一個對應的數組索引D x K x T。我想在數據框中將每個熊貓的條目n,d的地圖製作爲a[d][k][p[n,d]],對於所有可能的k導致N x D x K矩陣。對於如何在熊貓和諾普蒂圖書館中最有效地做到這一點,我可以獲得一些幫助嗎?熊貓和numpy花式索引

我其實然後把N x D的最後一個矩陣的一部分,沿着列產品留下一個N x K矩陣。最終的輸出可以是(慢)轉載由以下:

def generate_entry(i, j): 
     result = np.prod([alpha[s][j][int(p.loc[i][s])] for s in range(num_features) if not isNaN(p.loc[i][s]) ]) 
     return result 

    vgenerate_entry = np.vectorize(generate_entry) 
    result = np.fromfunction(vgenerate_entry, shape=(len(p), k), dtype=int) 

我覺得有些使用pandas.get_dummies將是矩陣乘法有益的,但我不能完全明白這一點。

下面是要快得多:

r = None 
    for i in range(num_features): 
     rel_data = pd.get_dummies(data.ix[:,i]) 
     rel_probs = alpha[i].T 
     prod = rel_data.dot(rel_probs) 
     prod[prod == 0] = 1 
     if r is None: 
      r = prod 
     else: 
      r = r.multiply(prod) 

    r = r.as_matrix() 
    r = r * pi 
    posteriers = r/np.sum(r, axis=1)[:, np.newaxis] 
+0

是的,這只是很慢。 – modesitt

+0

你可以分享嗎?你打算如何避免'p'中的NaN /這些NaN對應的輸出是什麼? – Divakar

+0

如果p [n,d]是nan,地圖應該去nan – modesitt

回答

3

這裏有一個方法來索引到NumPy的陣列a與熊貓數據幀p具有NaNs,這是要避免的,我們在這些填充一些值fillval地方 -

def fancy_indexing_avoid_NaNs(p, a, fillval = 1): 
    # Extract values from p and get NaN mask 
    pv = p.values 
    mask = np.isnan(pv) 

    # Get int version, replacing NaNs with some number, say 0 
    p_idx = np.where(mask, 0, pv).astype(int) 

    # FANCY-INDEX into array 'a' with those indices fron p 
    a_indexed_vals = a[np.arange(D), np.arange(K)[:,None,None],p_idx] 

    # FANCY-INDEX once more to replace the values set by NaNs as 1s, so 
    # that in the prod-reduction later on they would have no effect 
    a_indexed_vals[np.arange(K)[:,None,None],mask] = fillval 
    return a_indexed_vals 

fillval將取決於應用程序。在這種情況下,我們使用prod,所以fillval=1是有意義的,這不會影響結果。

原始的方法張貼由OP -

def generate_entry(i, j): 
    result = np.prod([a[s][j][int(p.loc[i][s])] for s in range(D) \ 
            if not np.isnan(p.loc[i][s]) ]) 
    return result 

vgenerate_entry = np.vectorize(generate_entry) 

採樣運行 -

In [154]: N,D,K,T = 3,4,5,6 
    ...: a = np.random.randint(0,5,(D,K,T)) 
    ...: 
    ...: p = pd.DataFrame(np.random.randint(0,T,(N,D)).astype(float)) 
    ...: p.iloc[2,3] = np.nan 
    ...: p.iloc[1,2] = np.nan 
    ...: 

In [155]: result = np.fromfunction(vgenerate_entry, shape=(len(p), K), dtype=int) 

In [156]: a_indexed_vals = fancy_indexing_avoid_NaNs(p, a) 

In [157]: out = a_indexed_vals.prod(2).T 

In [158]: np.allclose(out, result) 
Out[158]: True 
+0

不知道有關安排。並很好地使用了面膜 – modesitt