¿Cómo encuentro el índice de un elemento (por ejemplo, "Verdadero") en una serie o una columna?
Por ejemplo, tengo una columna donde quiero identificar la primera instancia donde ocurre un evento. Entonces lo escribo como
Variable = df["Force"] < eventEsto luego crea una serie booleana de datos donde es falso, hasta que la primera instancia se convierte en verdadero. Entonces, ¿cómo encuentro el índice del punto de datos?
¿Hay una mejor manera?
Use idxmax para encontrar la primera instancia del valor máximo. En este caso, True es el valor máximo.
df['Force'].lt(event).idxmax() Considere la muestra df :
df = pd.DataFrame(dict(Force=[5, 4, 3, 2, 1]), list('abcde')) df Force a 5 b 4 c 3 d 2 e 1 La primera instancia de Force menor que 3 está en el índice 'd' .
df['Force'].lt(3).idxmax() 'd' Tenga en cuenta que si ningún valor para Force es inferior a 3, el máximo será False y la primera instancia será la primera.
Considere también la alternativa argmax
df.Force.lt(3).values.argmax() 3 Devuelve la posición de la primera instancia de valor máximo. Luego puede usar esto para encontrar el valor index correspondiente:
df.index[df.Force.lt(3).values.argmax()] 'd' Además, en el futuro, argmax será un método de serie.
También puede probar first_valid_index con where .
df = pd.DataFrame([[5], [4], [3], [2], [1]], columns=["Force"]) df.Force.where(df.Force < 3).first_valid_index() 3 where reemplazará la parte que no cumple la condición con np.nan por defecto . Luego, encontramos el primer índice válido de la serie.
O esto: seleccione un subconjunto del artículo que le interesa, aquí Variable == 1 . Luego busque el primer elemento en su índice.
df = pd.DataFrame([[5], [4], [3], [2], [1]], columns=["Force"]) v = (df["Force"] < 3) v[v == 1].index[0] Bonificación: si necesita el índice de primera aparición de muchos tipos de elementos, puede usar drop_duplicates .
df = pd.DataFrame([["yello"], ["yello"], ["blue"], ["red"], ["blue"], ["red"]], columns=["Force"]) df.Force.drop_duplicates().reset_index() index Force 0 0 yello 1 2 blue 2 3 redAlgo más de trabajo...
df.Force.drop_duplicates().reset_index().set_index("Force").to_dict()["index"] {'blue': 2, 'red': 3, 'yello': 0}A continuación se muestra una solución sin pandas que me resulta fácil de adaptar:
import pandas as pd df = pd.DataFrame(dict(Force=[5, 4, 3, 2, 1]), list('abcde')) next(idx for idx, x in zip(df.index, df.Force) if x < 3) # dFunciona iterando al primer resultado de una expresión generadora.
Pandas parece tener un desempeño pobre en comparación:
df = pd.DataFrame(dict(Force=np.random.randint(0, 100000, 100000))) n = 99900 %timeit df['Force'].lt(n).idxmin() # 1000 loops, best of 3: 1.57 ms per loop %timeit df.Force.where(df.Force > n).first_valid_index() # 100 loops, best of 3: 1.61 ms per loop %timeit next(idx for idx, x in zip(df.index, df.Force) if x > n) # 10000 loops, best of 3: 100 µs per loop