tablas tabla que ejemplos curso crear con comandos biblioteca python pandas scipy scikit-learn sparse-matrix

tabla - que es python pandas



¿Cree eficientemente tablas dinámicas dispersas en pandas? (3)

Estoy trabajando para convertir una lista de registros con dos columnas (A y B) en una representación matricial. He estado usando la función de pivote dentro de los pandas, pero el resultado termina siendo bastante grande. ¿Los pandas admiten el giro en un formato disperso? Sé que puedo girarlo y luego convertirlo en una especie de representación dispersa, pero no es tan elegante como me gustaría. Mi objetivo final es usarlo como entrada para un modelo predictivo.

Alternativamente, ¿hay algún tipo de capacidad de giro escasa fuera de los pandas?

edición: aquí hay un ejemplo de un pivote no disperso

import pandas as pd frame=pd.DataFrame() frame[''person'']=[''me'',''you'',''him'',''you'',''him'',''me''] frame[''thing'']=[''a'',''a'',''b'',''c'',''d'',''d''] frame[''count'']=[1,1,1,1,1,1] frame person thing count 0 me a 1 1 you a 1 2 him b 1 3 you c 1 4 him d 1 5 me d 1 frame.pivot(''person'',''thing'') count thing a b c d person him NaN 1 NaN 1 me 1 NaN NaN 1 you 1 NaN 1 NaN

Esto crea una matriz que podría contener todas las combinaciones posibles de personas y cosas, pero no es escasa.

http://docs.scipy.org/doc/scipy/reference/sparse.html

Las matrices dispersas ocupan menos espacio porque pueden implicar cosas como NaN o 0. Si tengo un conjunto de datos muy grande, esta función pivotante puede generar una matriz que debería ser dispersa debido a la gran cantidad de NaN o 0. Tenía la esperanza de poder ahorrar una gran cantidad de espacio / memoria generando algo que no estaba muy extendido en lugar de crear una matriz densa y luego convertirla en escasa.


Aquí hay un método que crea una matriz escasa basada en datos e índices de persona y cosa. person_u y thing_u son listas que representan las entradas únicas para sus filas y columnas de pivote que desea crear. Nota: esto supone que su columna de recuento ya tiene el valor que desea.

from scipy.sparse import csr_matrix person_u = list(sort(frame.person.unique())) thing_u = list(sort(frame.thing.unique())) data = frame[''count''].tolist() row = frame.person.astype(''category'', categories=person_u).cat.codes col = frame.thing.astype(''category'', categories=thing_u).cat.codes sparse_matrix = csr_matrix((data, (row, col)), shape=(len(person_u), len(thing_u))) >>> sparse_matrix <3x4 sparse matrix of type ''<type ''numpy.int64''>'' with 6 stored elements in Compressed Sparse Row format> >>> sparse_matrix.todense() matrix([[0, 1, 0, 1], [1, 0, 0, 1], [1, 0, 1, 0]])

Sobre la base de su pregunta original, la matriz dispersa debe ser suficiente para sus necesidades, pero si desea tener un marco de datos disperso, puede hacer lo siguiente:

dfs=pd.SparseDataFrame([ pd.SparseSeries(sparse_matrix[i].toarray().ravel(), fill_value=0) for i in np.arange(sparse_matrix.shape[0]) ], index=person_u, columns=thing_u, default_fill_value=0) >>> dfs a b c d him 0 1 0 1 me 1 0 0 1 you 1 0 1 0 >>> type(dfs) pandas.sparse.frame.SparseDataFrame


La respuesta publicada anteriormente por @khammel fue útil, pero desafortunadamente ya no funciona debido a los cambios en pandas y Python. Lo siguiente debe producir el mismo resultado:

from scipy.sparse import csr_matrix from pandas.api.types import CategoricalDtype person_c = CategoricalDtype(sorted(frame.person.unique()), ordered=True) thing_c = CategoricalDtype(sorted(frame.thing.unique()), ordered=True) row = frame.person.astype(person_c).cat.codes col = frame.thing.astype(thing_c).cat.codes sparse_matrix = csr_matrix((frame["count"], (row, col)), / shape=(person_c.categories.size, thing_c.categories.size)) >>> sparse_matrix <3x4 sparse matrix of type ''<class ''numpy.int64''>'' with 6 stored elements in Compressed Sparse Row format> >>> sparse_matrix.todense() matrix([[0, 1, 0, 1], [1, 0, 0, 1], [1, 0, 1, 0]], dtype=int64) dfs = pd.SparseDataFrame(sparse_matrix, / index=person_u.categories, / columns=thing_u.categories, / default_fill_value=0) >>> dfs a b c d him 0 1 0 1 me 1 0 0 1 you 1 0 1 0

Los principales cambios fueron:

  • .astype() ya no acepta "categórico". Tienes que crear un objeto CategoricalDtype.
  • sort() ya no funciona

Otros cambios fueron más superficiales:

  • Usar los tamaños de categoría en lugar de una longitud de los objetos de la serie sin formato, simplemente porque no quería hacer otro objeto innecesariamente
  • La entrada de datos para csr_matrix ( frame["count"] ) no necesita ser un objeto de lista
  • pandas SparseDataFrame acepta un objeto scipy.sparse directamente ahora

Tuve un problema similar y me tropecé con este post. La única diferencia fue que tenía dos columnas en el DataFrame que definen la "dimensión de fila" ( i ) de la matriz de salida. Pensé que esto podría ser una generalización interesante, usé el grouper :

# function import pandas as pd from scipy.sparse import csr_matrix def df_to_sm(data, vars_i, vars_j): grpr_i = data.groupby(vars_i).grouper idx_i = grpr_i.group_info[0] grpr_j = data.groupby(vars_j).grouper idx_j = grpr_j.group_info[0] data_sm = csr_matrix((data[''val''].values, (idx_i, idx_j)), shape=(grpr_i.ngroups, grpr_j.ngroups)) return data_sm, grpr_i, grpr_j # example data = pd.DataFrame({''var_i_1'' : [''a1'', ''a1'', ''a1'', ''a2'', ''a2'', ''a3''], ''var_i_2'' : [''b2'', ''b1'', ''b1'', ''b1'', ''b1'', ''b4''], ''var_j_1'' : [''c2'', ''c3'', ''c2'', ''c1'', ''c2'', ''c3''], ''val'' : [1, 2, 3, 4, 5, 6]}) data_sm, _, _ = df_to_sm(data, [''var_i_1'', ''var_i_2''], [''var_j_1'']) data_sm.todense()