usar tutorial tablas recorrer para notebook leer hacer graficar funciones español documentacion datos data curso como python pandas rows matching

tablas - pandas python tutorial español pdf



Compare los marcos de datos de Python Pandas para las filas coincidentes (2)

@ Andrew: Creo que encontré una manera de eliminar las filas de un marco de datos que ya están presentes en otro (es decir, para responder mi EDIT) sin usar bucles; avíseme si no está de acuerdo o si mi OP + EDIT no fue clara declara esto:

ESTO FUNCIONA

Las columnas para ambos marcos de datos son siempre las mismas: A , B , C y D Con esto en mente, basado en gran medida en el enfoque de Andrew, aquí se explica cómo eliminar las filas de df2 que también están presentes en df1 :

common_cols = df1.columns.tolist() #generate list of column names df12 = pd.merge(df1, df2, on=common_cols, how=''inner'') #extract common rows with merge df2 = df2[~df2[''A''].isin(df12[''A''])]

La línea 3 hace lo siguiente:

  • Extraiga solo filas de df2 que no coincidan con las filas de df1 :
  • Para que 2 filas sean diferentes, CUALQUIER columna de una fila debe
    necesariamente será diferente que la columna correspondiente en otra fila.
  • Aquí, elegí la columna A para hacer esta comparación, es
    es posible usar cualquiera de los nombres de columna, pero no TODOS
    nombres de columna

NOTA: este método es esencialmente el equivalente del SQL NOT IN() .

Tengo este DataFrame ( df1 ) en Pandas:

df1 = pd.DataFrame(np.random.rand(10,4),columns=list(''ABCD'')) print df1 A B C D 0.860379 0.726956 0.394529 0.833217 0.014180 0.813828 0.559891 0.339647 0.782838 0.698993 0.551252 0.361034 0.833370 0.982056 0.741821 0.006864 0.855955 0.546562 0.270425 0.136006 0.491538 0.445024 0.971603 0.690001 0.911696 0.065338 0.796946 0.853456 0.744923 0.545661 0.492739 0.337628 0.576235 0.219831 0.946772 0.752403 0.164873 0.454862 0.745890 0.437729

Me gustaría verificar si alguna fila (todas las columnas) de otro marco de datos ( df2 ) está presente en df1 . Aquí está df2 :

df2 = df1.ix[4:8] df2.reset_index(drop=True,inplace=True) df2.loc[-1] = [2, 3, 4, 5] df2.loc[-2] = [14, 15, 16, 17] df2.reset_index(drop=True,inplace=True) print df2 A B C D 0.855955 0.546562 0.270425 0.136006 0.491538 0.445024 0.971603 0.690001 0.911696 0.065338 0.796946 0.853456 0.744923 0.545661 0.492739 0.337628 0.576235 0.219831 0.946772 0.752403 2.000000 3.000000 4.000000 5.000000 14.000000 15.000000 16.000000 17.000000

Intenté usar df.lookup para buscar una fila a la vez. Lo hice de esta manera:

list1 = df2.ix[0].tolist() cols = df1.columns.tolist() print df1.lookup(list1, cols)

pero recibí este mensaje de error:

File "C:/Users/test.py", line 19, in <module> print df1.lookup(list1, cols) File "C:/python27/lib/site-packages/pandas/core/frame.py", line 2217, in lookup raise KeyError(''One or more row labels was not found'') KeyError: ''One or more row labels was not found''

También probé .all() usando:

print (df2 == df1).all(1).any()

pero recibí este mensaje de error:

File "C:/Users/test.py", line 12, in <module> print (df2 == df1).all(1).any() File "C:/python27/lib/site-packages/pandas/core/ops.py", line 884, in f return self._compare_frame(other, func, str_rep) File "C:/python27/lib/site-packages/pandas/core/frame.py", line 3010, in _compare_frame raise ValueError(''Can only compare identically-labeled '' ValueError: Can only compare identically-labeled DataFrame objects

También probé isin() así:

print df2.isin(df1)

pero obtuve False todas partes, lo cual no es correcto:

A B C D False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False

¿Es posible buscar un conjunto de filas en un DataFrame, comparándolo con las filas de otro marco de datos?

EDITAR: ¿Es posible soltar filas df2 si esas filas también están presentes en df1 ?


Una posible solución a su problema sería usar merge . Verificar si alguna fila (todas las columnas) de otro marco de datos (df2) está presente en df1 es equivalente a determinar la intersección de los dos marcos de datos. Esto se puede lograr usando la siguiente función:

pd.merge(df1, df2, on=[''A'', ''B'', ''C'', ''D''], how=''inner'')

Por ejemplo, si df1 era

A B C D 0 0.403846 0.312230 0.209882 0.397923 1 0.934957 0.731730 0.484712 0.734747 2 0.588245 0.961589 0.910292 0.382072 3 0.534226 0.276908 0.323282 0.629398 4 0.259533 0.277465 0.043652 0.925743 5 0.667415 0.051182 0.928655 0.737673 6 0.217923 0.665446 0.224268 0.772592 7 0.023578 0.561884 0.615515 0.362084 8 0.346373 0.375366 0.083003 0.663622 9 0.352584 0.103263 0.661686 0.246862

y df2 se definió como:

A B C D 0 0.259533 0.277465 0.043652 0.925743 1 0.667415 0.051182 0.928655 0.737673 2 0.217923 0.665446 0.224268 0.772592 3 0.023578 0.561884 0.615515 0.362084 4 0.346373 0.375366 0.083003 0.663622 5 2.000000 3.000000 4.000000 5.000000 6 14.000000 15.000000 16.000000 17.000000

La función pd.merge(df1, df2, on=[''A'', ''B'', ''C'', ''D''], how=''inner'') produce:

A B C D 0 0.259533 0.277465 0.043652 0.925743 1 0.667415 0.051182 0.928655 0.737673 2 0.217923 0.665446 0.224268 0.772592 3 0.023578 0.561884 0.615515 0.362084 4 0.346373 0.375366 0.083003 0.663622

Los resultados son todas las filas (todas las columnas) que están en df1 y df2.

También podemos modificar este ejemplo si las columnas no son las mismas en df1 y df2 y solo comparar los valores de fila que son iguales para un subconjunto de las columnas. Si modificamos el ejemplo original:

df1 = pd.DataFrame(np.random.rand(10,4),columns=list(''ABCD'')) df2 = df1.ix[4:8] df2.reset_index(drop=True,inplace=True) df2.loc[-1] = [2, 3, 4, 5] df2.loc[-2] = [14, 15, 16, 17] df2.reset_index(drop=True,inplace=True) df2 = df2[[''A'', ''B'', ''C'']] # df2 has only columns A B C

Luego podemos mirar las columnas comunes usando common_cols = list(set(df1.columns) & set(df2.columns)) entre los dos marcos de datos y luego combinar:

pd.merge(df1, df2, on=common_cols, how=''inner'')

EDITAR: Nueva pregunta (comentarios), habiendo identificado las filas de df2 que también estaban presentes en el primer marco de datos (df1), ¿es posible tomar el resultado de pd.merge () y luego soltar las filas de df2 que están también presente en df1

No conozco una forma sencilla de lograr la tarea de eliminar las filas de df2 que también están presentes en df1. Dicho esto, puedes usar lo siguiente:

ds1 = set(tuple(line) for line in df1.values) ds2 = set(tuple(line) for line in df2.values) df = pd.DataFrame(list(ds2.difference(ds1)), columns=df2.columns)

Probablemente exista una mejor manera de lograr esa tarea, pero no estoy al tanto de tal método / función.

EDITAR 2: Cómo soltar las filas de df2 que también están presentes en df1 como se muestra en la respuesta @WR.

El método proporcionado df2[~df2[''A''].isin(df12[''A''])] no tiene en cuenta todos los tipos de situaciones. Considere los siguientes marcos de datos:

df1:

A B C D 0 6 4 1 6 1 7 6 6 8 2 1 6 2 7 3 8 0 4 1 4 1 0 2 3 5 8 4 7 5 6 4 7 1 1 7 3 7 3 4 8 5 2 8 8 9 3 2 8 4

df2:

A B C D 0 1 0 2 3 1 8 4 7 5 2 4 7 1 1 3 3 7 3 4 4 5 2 8 8 5 1 1 1 1 6 2 2 2 2

df12:

A B C D 0 1 0 2 3 1 8 4 7 5 2 4 7 1 1 3 3 7 3 4 4 5 2 8 8

El uso de los DataFrames anteriores con el objetivo de eliminar filas de df2 que también están presentes en df1 daría como resultado lo siguiente:

A B C D 0 1 1 1 1 1 2 2 2 2

Las filas (1, 1, 1, 1) y (2, 2, 2, 2) están en df2 y no en df1. Desafortunadamente, el uso del método proporcionado ( df2[~df2[''A''].isin(df12[''A''])] ) da como resultado:

A B C D 6 2 2 2 2

Esto ocurre porque el valor de 1 en la columna A se encuentra tanto en el DataFrame de intersección (es decir (1, 0, 2, 3)) como en df2 y, por lo tanto, elimina tanto (1, 0, 2, 3) como (1, 1, 1, 1). Esto no es intencionado ya que la fila (1, 1, 1, 1) no está en df1 y no debe eliminarse.

Creo que lo siguiente proporcionará una solución. Crea una columna ficticia que luego se utiliza para subconjugar el DataFrame a los resultados deseados:

df12[''key''] = ''x'' temp_df = pd.merge(df2, df12, on=df2.columns.tolist(), how=''left'') temp_df[temp_df[''key''].isnull()].drop(''key'', axis=1)