Compara dos columnas utilizando pandas

Usando esto como punto de partida:

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']] df = pd.DataFrame(a, columns=['one', 'two', 'three']) Out[8]: one two three 0 10 1.2 4.2 1 15 70 0.03 2 8 5 0 

Quiero usar algo como una statement if dentro de pandas.

 if df['one'] >= df['two'] and df['one'] <= df['three']: df['que'] = df['one'] 

Básicamente, verifique cada fila a través de la sentencia if , cree una nueva columna.

Los documentos dicen usar .all pero no hay ningún ejemplo …

Podrías usar np.where . Si cond es una matriz booleana, y A y B son matrices, entonces

 C = np.where(cond, A, B) 

define que C es igual a A donde cond es Verdadero y B donde cond es Falso.

 import numpy as np import pandas as pd a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']] df = pd.DataFrame(a, columns=['one', 'two', 'three']) df['que'] = np.where((df['one'] >= df['two']) & (df['one'] <= df['three']) , df['one'], np.nan) 

rendimientos

  one two three que 0 10 1.2 4.2 10 1 15 70 0.03 NaN 2 8 5 0 NaN 

Si tiene más de una condición, entonces podría usar np.select en su lugar. Por ejemplo, si desea que df['que'] igual a df['two'] cuando df['one'] < df['two'] , entonces

 conditions = [ (df['one'] >= df['two']) & (df['one'] <= df['three']), df['one'] < df['two']] choices = [df['one'], df['two']] df['que'] = np.select(conditions, choices, default=np.nan) 

rendimientos

  one two three que 0 10 1.2 4.2 10 1 15 70 0.03 70 2 8 5 0 NaN 

Si podemos asumir que df['one'] >= df['two'] cuando df['one'] < df['two'] es False, entonces las condiciones y opciones podrían simplificarse para

 conditions = [ df['one'] < df['two'], df['one'] <= df['three']] choices = [df['two'], df['one']] 

(La suposición puede no ser cierta si df['one'] o df['two'] contienen NaNs.)


Tenga en cuenta que

 a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']] df = pd.DataFrame(a, columns=['one', 'two', 'three']) 

define un DataFrame con valores de cadena. Ya que se ven numéricos, es mejor que conviertas esas cadenas en flotadores:

 df2 = df.astype(float) 

Sin embargo, esto cambia los resultados, ya que las cadenas comparan carácter por carácter, mientras que las flotaciones se comparan numéricamente.

 In [61]: '10' <= '4.2' Out[61]: True In [62]: 10 <= 4.2 Out[62]: False 

Puede utilizar .equals para columnas o marcos de datos completos.

 df['col1'].equals(df['col2']) 

Si son iguales, esa afirmación devolverá True , de lo contrario False .

Podrías usar aplicar () y hacer algo como esto.

 df['que'] = df.apply(lambda x : x['one'] if x['one'] >= x['two'] and x['one'] <= x['three'] else "", axis=1) 

o si prefieres no usar un lambda

 def que(x): if x['one'] >= x['two'] and x['one'] <= x['three']: return x['one'] else: '' df['que'] = df.apply(que, axis=1) 

Una forma es usar una serie booleana para indexar la columna df['one'] . Esto le da una nueva columna donde las entradas True tienen el mismo valor que la misma fila que df['one'] y los valores False son NaN .

La serie booleana solo está dada por su sentencia if (aunque es necesario usar & lugar de and ):

 >>> df['que'] = df['one'][(df['one'] >= df['two']) & (df['one'] <= df['three'])] >>> df one two three que 0 10 1.2 4.2 10 1 15 70 0.03 NaN 2 8 5 0 NaN 

Si desea que los valores de NaN sean reemplazados por otros valores, puede usar el método fillna en la nueva columna de que . He usado 0 lugar de la cadena vacía aquí:

 >>> df['que'] = df['que'].fillna(0) >>> df one two three que 0 10 1.2 4.2 10 1 15 70 0.03 0 2 8 5 0 0 

Envuelva cada condición individual entre paréntesis y luego use el operador & para combinar las condiciones:

 df.loc[(df['one'] >= df['two']) & (df['one'] <= df['three']), 'que'] = df['one'] 

Puede rellenar las filas no coincidentes simplemente usando ~ (el operador "no") para invertir la coincidencia:

 df.loc[~ ((df['one'] >= df['two']) & (df['one'] <= df['three'])), 'que'] = '' 

Debe usar & y ~ lugar de and y not porque los operadores & y ~ funcionan elemento por elemento.

El resultado final:

 df Out[8]: one two three que 0 10 1.2 4.2 10 1 15 70 0.03 2 8 5 0 

Creo que lo más cercano a la intuición del OP es una statement en línea si:

 df['que'] = (df['one'] if ((df['one'] >= df['two']) and (df['one'] <= df['three']))