Es un módulo Python para el manejo de arrays (vectores) y matrices. El componente esencial es el tipo array. Este notebook es un resumen de http://goo.gl/fiLYpb.
Cuando uses numpy/matplotlib en IPython, evitar usar pylab
In [1]:
import numpy as np
a1 = np.array([])
a1
Out[1]:
A diferencia de la lista estándar de Python, todos los elementos de un array deben ser del mismo tipo.
In [2]:
a1.dtype
Out[2]:
Pero se puede convertir a otro:
In [3]:
aux = a1.astype(int)
print(aux.dtype)
print(aux)
Para especificar el tipo de los datos se pueden utilizar los tipos de Python, sus nombres como cadenas o variables definidas en el módulo numpy:
In [4]:
np.array([1], dtype=int)
np.array([1], dtype='float64')
np.array([1], dtype=np.complex128)
Out[4]:
Los operadores están sobrecargados con su semántica matemática:
In [5]:
a1 = np.array([1, 2, 3])
print(a1 + [4, 5, 6])
print(a1 * 3)
print(a1 * [4, 5, 6])
print(a1 >= 2)
Y además son multidimencionales:
In [6]:
a2 = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
a2
Out[6]:
In [7]:
print("El array tiene {} dimensiones".format(a2.ndim))
print("Su tamaño es {0[0]} filas y {0[1]} columnas".format(a2.shape))
Es posible ver un array con un estructura diferente. Es importante señalar que esta operación no crea un array nuevo ni mueve los datos, solo los accede de un modo diferente.
In [8]:
a3 = np.array(range(8))
a3
Out[8]:
In [9]:
a3.reshape(2, 4)
Out[9]:
In [10]:
x = np.arange(1,5).reshape(2,2)
y = np.arange(5,9).reshape(2,2)
print(x * y)
print(np.dot(x, y))
In [11]:
np.arange(10)
Out[11]:
La función linspace()
es similar, pero es más adecuada para valores flotantes. Se puede indicar la cantidad de valores a crear entre los límites indicados.
In [12]:
x = np.linspace(0, 10, num=20)
x
Out[12]:
In [13]:
np.zeros((2,3))
Out[13]:
In [14]:
np.ones(6)
Out[14]:
In [15]:
np.identity(5)
Out[15]:
In [16]:
np.diag([1, 2, 3])
Out[16]:
In [17]:
np.random.rand(5)
Out[17]:
In [18]:
np.random.rand(3, 4)
Out[18]:
In [19]:
np.empty((2,3))
Out[19]:
Las funciones matemáticas de numpy
aceptan y devuelven arrays en lugar de valores escalares.
In [20]:
sin_x = np.sin(x)
print(sin_x)
abs_sin_x = abs(sin_x)
print(abs_sin_x)
Por tanto, linspace
nos da un espacio unidimensional discreto. mgrid
ofrece algo parecido para un espacio bidimensional. Devuelve dos arrays bidimensionales, uno creciente por columnas y otro por filas.
In [21]:
a_2D = np.mgrid[0:5,0:5]
a_2D
Out[21]:
In [22]:
x, y = a_2D
z = (x+y) ** 2
z
Out[22]:
In [23]:
a2
Out[23]:
In [24]:
a2[1,2]
Out[24]:
In [25]:
a2[:,2]
Out[25]:
In [26]:
a2[1,1:]
Out[26]:
In [27]:
a4d = np.arange(256).reshape(4,4,4,-1)
a4d[1,:,:,2]
Out[27]:
Es posible indexar un array usando una lista:
In [28]:
a = np.array(list(reversed(range(20))))
indexes = [2, 4, 8, 12]
a[indexes]
Out[28]:
También con un array de booleanos:
In [69]:
a = np.arange(20)
indexes = np.array([i > 16 or not i%3 for i in a], dtype=bool)
indexes = np.array([True] * 15)
print(indexes)
a[indexes]
Out[69]:
Y estas indexación se pueden usar en una asignación múltiple:
In [30]:
a[indexes] = -1
a
Out[30]:
In [31]:
a25 = np.arange(25).reshape(5, 5)
for row in a25:
print(row)
Se puede iterar como un array plano (el array no es modificado):
In [32]:
for x in a25.flat:
print(x)
In [70]:
b = a2.copy()
b1 = b[:,2]
print(b1)
b1[2]= 3000
print(b)
b[1,:] = 666
print(b)
print(b1)
In [34]:
a2
Out[34]:
Añadir elementos crea un array nuevo:
In [35]:
np.append(a2, 3)
Out[35]:
In [36]:
a2
Out[36]:
Se puede crear una vista de un array completo:
In [37]:
aux = a2.view()
aux.shape = 2,6
print(aux)
print(a2)
In [38]:
a2
Out[38]:
In [39]:
a2.flags
Out[39]:
In [40]:
for attr in ['shape', 'strides', 'ndim', 'size', 'dtype', 'itemsize', 'nbytes']:
print("- {:10} {}".format(attr, getattr(a2, attr)))
In [41]:
a2.item((1,0))
Out[41]:
In [42]:
a2.tolist()
Out[42]:
In [43]:
a2.tostring()
Out[43]:
In [44]:
a2.copy()
Out[44]:
In [45]:
a2.view(dtype=np.int16)
Out[45]:
In [46]:
a2.fill(1)
a2
Out[46]:
In [47]:
a2 = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
a2.transpose()
Out[47]:
In [48]:
aux = a2.copy()
aux.resize(5,5)
aux
Out[48]:
In [49]:
a2
Out[49]:
In [50]:
aux = np.array([[3, 2], [1, 6]])
aux.sort(axis=1)
aux
Out[50]:
In [51]:
aux.sort(axis=0)
aux
Out[51]:
In [52]:
a2.diagonal()
Out[52]:
In [53]:
a2
Out[53]:
In [54]:
print(a2.min())
print(a2.max())
print(a2.sum())
print(a2.mean())
print(a2.var())
print(a2.sum(axis=0))
print(a2.sum(axis=1))
In [55]:
from numpy.linalg import solve
# The system of equations we want to solve for (x0,x1,x2):
# 3 * x0 + 1 * x1 + 5 * x2 = 6
# 1 * x0 + 8 * x2 = 7
# 2 * x0 + 1 * x1 + 4 * x2 = 8
a = np.array([[3, 1, 5], [1, 0, 8],[2, 1, 4]])
b = np.array([6, 7, 8])
solution = solve(a, b)
print(solution)
print(np.dot(a, solution)) # Just checking if we indeed obtain the righthand side
In [56]:
a = np.arange(4)
b = np.array([[x] for x in range(4)])
b = a.reshape(4,1)
print(a)
print(b)
a * b
Out[56]:
In [57]:
np.fromstring("1 2 3 4 5", sep=" ", dtype=int)
Out[57]:
In [58]:
a2 = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
In [59]:
np.array2string(a2)
Out[59]:
In [60]:
with file('tmp/array', 'w') as fd:
a2.tofile(fd)
fd = file('tmp/array')
np.fromfile(fd, np.int64)
fd.close()
Out[60]:
In [61]:
!hexdump tmp/array
In [62]:
with file('tmp/array_pickle', 'w') as fd:
a2.dump(fd)
np.load(file('tmp/array_pickle'))
Out[62]:
In [63]:
!hexdump -C tmp/array_pickle
In [64]:
!head -n8 graphs/dodecahedral.edgelist
In [65]:
np.loadtxt('graphs/dodecahedral.edgelist')[:8,:]
Out[65]:
In [73]:
# url = 'https://gist.github.com/chriddyp/8818473/raw/d8c73ff66a190a84eb8c6c19df4d8865673234ca/2007gapminder.csv'
url = 'http://arco.esi.uclm.es/~david.villa/puff/2007gapminder.csv'
data = np.genfromtxt(url, delimiter=',', dtype=None, names=True)
print("ndim: {}".format(data.ndim))
print("shape: {}".format(data.shape))
print("dtype: {}".format(data.dtype))
In [74]:
data[:10]
Out[74]:
In [75]:
data['Country'][:30]
Out[75]:
Media de la rentas per cápita de cada pais:
In [78]:
np.mean(data['gdpPercap'])
Out[78]:
Media de renta per cápita en Europa
In [79]:
europe_index = data['Continent'] == 'Europe'
europe_countries = data[europe_index]
europe_countries['Country']
Out[79]:
In [80]:
np.mean(europe_countries['gdpPercap'])
Out[80]:
Población mundial
In [81]:
population = data['Population']
np.sum(population)
Out[81]:
Población media (por páis):
In [82]:
int(np.mean(population))
Out[82]:
Renta per cápita media mundial
In [77]:
pib = np.sum(data['Population'] * data['gdpPercap'])
pob_total = np.sum(data['Population'])
print(pib/pob_total)
Desviación típica de población:
In [83]:
np.std(population)
Out[83]:
País con mayor población:
In [84]:
data[np.argmax(population)][0]
Out[84]:
Los cinco países con mayor renta per cápita:
In [89]:
percap_sorted = np.sort(data, order='gdpPercap')
percap_sorted[-5:][::-1]
Out[89]:
PIB de todos los países:
In [104]:
import numpy.lib.recfunctions as rfn
pibs = population * data['gdpPercap']
arrays = data['Country'], pibs
country_pibs = rfn.merge_arrays(arrays, flatten = True, usemask = False)
country_pibs[:20]
Out[104]:
Los cinco paises con el PIB más alto
In [111]:
np.sort(country_pibs, order='f1')[-5:][::-1]
Out[111]: