2014-12-22 1 views
6

Oczekiwano, że np.fromfunction(lambda i: 1, (4,), dtype=int) zwróci array([1, 1, 1, 1]), ale zamiast tego zwróci liczbę całkowitą 1. Czy ktoś może mi wytłumaczyć, dlaczego numpy.fromfunction zachowuje się w ten sposób? Wydaje się, że ma to coś wspólnego z definicją funkcji anonimowej (tj. Czy faktycznie użyto parametru funkcji).Nieoczekiwany wynik - numpy fromfunction ze stałymi funkcjami

>>> import numpy as np 

>>> np.fromfunction(lambda i: i, (4,), dtype=int) 
array([0, 1, 2, 3]) 

>>> np.fromfunction(lambda i: 1, (4,), dtype=int) 
1 

>>> np.fromfunction(lambda i: 1 + i*0, (4,), dtype=int) 
array([1, 1, 1, 1]) 

EDYCJA: aby wyjaśnić, moim ostatecznym celem nie jest stworzenie array([1, 1, 1, 1]) przy użyciu tej metody. Raczej Robię wezwanie postaci

np.fromfunction(lambda i: **an expression that doesn't depend on i**, (n,)) 

Innymi słowy, próbuję zainicjować tablicę numpy poprzez wielokrotne wykonanie połączenia do niektórych funkcji. (Jest to wezwanie do np.random.random() w tej funkcji, więc nie robię nadmiarowych połączeń).

+0

Jeśli wyrażenie nie zależy od 'i', podejrzewam, że można zastąpić użycie' a = np.fromfunction (lambda i: ** wyrażenie, które nie zależy od i **, (n,)) 'z czymś takim jak' a = ** wyrażenie, które nie zależy od i ** ', aw wyrażeniu użyj czegoś takiego jak' np.ones (n) ',' np.arange (n) ', itp., aby wyrażenie tworzyło tablicę o odpowiednim rozmiarze. –

+0

@WarrenWeckesser Nie jestem pewien, czy rozumiem. Czy twoja metoda zadziała, nawet jeśli jest wywołanie 'np.random.random()' wewnątrz '** wyrażenie, które nie zależy od i **'? –

+0

Możesz użyć argumentu 'size' z' np.random.random'. Jeśli twoje wyrażenie to, powiedzmy, "4 * u ** 2 + 1", gdzie 'u' jest przypadkowe, możesz napisać' a = 4 * np.random.losowy (rozmiar = n) ** 2 + 1'. –

Odpowiedz

6

Nie jest dobrze wyjaśnione w dokumentacji func argumentu w fromfunction docstring że func nazywa się po prostu raz, z argumentami tablicowymi.

W tym przykładzie

np.fromfunction(lambda i: i, (4,), dtype=int) 

funkcja anonimowa nazywa się raz z argumentem i jest tablica [0, 1, 2, 3]. Aby to sprawdzić, można zrobić:

In [10] from __future__ import print_function 

In [11]: np.fromfunction(lambda i: print("i = %r" % (i,)), (4,), dtype=int) 
i = array([0, 1, 2, 3]) 

W tym przypadku, gdzie func zwraca 1,

np.fromfunction(lambda i: 1, (4,), dtype=int) 

ponieważ wartość zwrócona przez jednego połączenia wynosi 1, tablica, który jest tworzony zawiera tylko 1

Nie jest jasne, dlaczego chcesz użyć fromfunction, aby utworzyć tablicę 1s zamiast, powiedzmy, np.ones, ale jeśli masz na myśli coś bardziej skomplikowanego, oto jeden ze sposobów, w jaki możesz to zrobić, używając np.ones_like:

In [14]: np.fromfunction(lambda i: np.ones_like(i), (4,), dtype=int) 
Out[14]: array([1, 1, 1, 1]) 
+2

Wydaje się to dość nieintuicyjne. Czy istnieje funkcja, która robi to, co OP ma zamiar zrobić? – Rufflewind

+0

Dzięki - to naprawdę oczyszcza zachowanie funkcji. –

6

@Warren Weckesser wyjaśnił, dlaczego tak się dzieje (docs NumPy są nieco mylące tutaj i nigdzie nie było jasne, że fromfunction spodziewa wektor). Jeśli chcesz, aby swoją pracę lambda funkcyjny z fromfunction można wektorować go wyraźnie:

In [1]: func = lambda i: 1 
In [1]: vfunc = np.vectorize(func) 
In [2]: np.fromfunction(vfunc, (4,), dtype=int) 
Out[2]: array([1, 1, 1, 1]) 

Ale w tym przypadku zastosowania, to bym pomyślał

np.ones(4, dtype=int) 

(być może czasy stała) byłoby lepszy.

+0

Ach, warto to wiedzieć. Dzięki! –