que matrices funcion elementos data crear columna arreglo array agregar python arrays numpy scipy sparse-matrix

matrices - ¿Qué tipo de matriz de Python sería esto? ¿Ya existe en Python?



numpy array que es (4)

Tengo una matriz numpy:

m = array([[4, 0, 9, 0], [0, 7, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5]])

Las 4 columnas de m están etiquetadas:

c = array([ 10, 20, 30, 40])

Quiero poder cortar un objeto o tal que:

o.vals[0,:] = array([4, 9]) o.vals[1,:] = array([7,]) o.vals[2,:] = array([]) o.vals[3,:] = array([5]) o.cols[0,:] = array([10, 30] )# the non-zero column labels from row 0 o.cols[1,:] = array([20,]) o.cols[2,:] = array([]) o.cols[3,:] = array([40])

¿Existe un objeto Python existente que me permita hacer esto?

He analizado Scipy Sparse Matrices , pero no es exactamente lo que estoy buscando.

UNA ACTUALIZACIÓN el 17 de agosto de 2015: He tenido algunas ideas y se me ocurrió esto, que es casi lo mismo que describí la semana pasada:


Podría usar pandas ( http://pandas.pydata.org/ ). (dado que probé scipy/numpy que no son paquetes de biblioteca estándar de Python, supongo que está bien sugerir otro paquete).

Un DataFrame es un objeto que le permite realizar todas sus operaciones, y muchas más.

import numpy as np import pandas as pd m = array([[4, 0, 9, 0], [0, 7, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5]]) # create a dataframe df = pd.DataFrame(m, columns=[10,20,30,40]) # replace 0 with NaN (to make use of pandas `dropna`) df.replace(0, np.NaN, inplace=True) # values per row df.irow(0).dropna().as_matrix() array([ 4., 9.]) df.irow(1).dropna().as_matrix() array([ 7.]) df2.irow(2).dropna().as_matrix() array([], dtype=float64) # column labels (as list) df.irow(1).dropna().index.tolist() [10, 30] # or non-zero values per column? df.icol(0).dropna().as_matrix() array([ 4.]) # ...

También puede combinar la etiqueta y el valor de la columna, ya que el retorno normal del dropna es un DataFrame.

non_zero_1 = df.irow(0).dropna() labels_1 = non_zero_1.index Int64Index([10, 30], dtype=''int64'')

Lo mejor es probar Pandas y ver si se ajusta a tus necesidades. Y también eche un vistazo a la gran introducción ( http://pandas.pydata.org/pandas-docs/stable/10min.html ).


Puede acercarse a lo que desea con una matriz dispersa de CSR:

import scipy.sparse as sps m_csr = sps.csr_matrix(m)

Ahora puede implementar funciones similares a lo que está buscando de esta manera:

def vals(sps_mat, row): row_slice = slice(sps_mat.indptr[row], sps_mat.indptr[row+1]) return sps_mat.data[row_slice] def cols(sps_mat, col_labels, row): col_labels = np.asarray(col_labels) row_slice = slice(sps_mat.indptr[row], sps_mat.indptr[row+1]) return col_labels[sps_mat.indices[row_slice]]

Usando estas funciones obtenemos:

>>> for row in range(m_csr.shape[0]): ... print vals(m_csr, row) ... [4 9] [7] [] [5] >>> for row in range(m_csr.shape[0]): ... print cols(m_csr, [10, 20, 30, 40], row) ... [10 30] [20] [] [40]

Esto será muy eficiente en matrices grandes, aunque la sintaxis no es exactamente lo que usted quería.


Puede acercarse a lo que desea definiendo una clase que contenga m y c :

import numpy as np class O(object): def __init__(self, m, c): self.m, self.c = m, c def vals(self, i): return self.m[i][self.m[i]!=0] def cols(self, i): return self.c[self.m[i]!=0] m = np.array([[4, 0, 9, 0], [0, 7, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5]]) c = np.array([ 10, 20, 30, 40]) o = O(m, c) for i in range(4): print ''o.vals({0:d}) = {1}''.format(i, o.vals(i)) for i in range(4): print ''o.cols({0:d}) = {1}''.format(i, o.cols(i))

Devoluciones:

o.vals(0) = [4 9] o.vals(1) = [7] o.vals(2) = [] o.vals(3) = [5] o.cols(0) = [10 30] o.cols(1) = [20] o.cols(2) = [] o.cols(3) = [40]

(Sin embargo, podría ser más fácil usar la indexación, m[i][m[i]!=0 c[m[i]!=0] directamente).


Puede usar una clase anidada y sobrecargar el atributo __getitem__ de sus objetos:

import numpy as np class indexer: def __init__(self,arr): self.arr=arr self.d=self.caldict(self.arr) self.vals=self.values(self.arr,self.d) self.cols=self.columns(self.d) def caldict(self,arr,dd={}): inds=np.array(np.nonzero(arr)).T for i,j in inds: dd.setdefault(i,[]).append(j) return dd class values: def __init__(self,arr,d): self.arr=arr self.d=d def __getitem__(self,index): try: return self.arr.take(index,axis=0)[self.d[index]] except KeyError: return [] class columns: def __init__(self,d): self.d=d self.c=np.array([ 10, 20, 30, 40]) def __getitem__(self,index): try: return self.c.take(self.d[index]) except KeyError: return []

Manifestación:

m=np.array([[4, 0, 9, 0], [0, 7, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5]]) o=indexer(m) print o.vals[0],''/n'',o.vals[1],''/n'',o.vals[2],''/n'',o.vals[3] print ''------------------'' print o.cols[0],''/n'',o.cols[1],''/n'',o.cols[2],''/n'',o.cols[3] [4 9] [7] [] [5] ------------------ [10 30] [20] [] [40]