0

Having a df with pandas, I want to have the first index occurrence of "V1" | "V2" if possible without having to scan all the DF. Can I make it stop at the first match ?

I started doing i = df[(df["track"] == "V1") | (df["track"] == "V2")].iloc[0] but I got the full row and have a list.

Ragnar
  • 2,550
  • 6
  • 36
  • 70

5 Answers5

2

Looks like you want:

df.track.isin(['V1', 'V2']).idxmax()

If you want to stop on the first match here's one way using a generator comprehension:

match = {'V1', 'V2'}
next((ix for ix, i in enumerate(df.track.values) if i in match), None)
# 1
yatu
  • 86,083
  • 12
  • 84
  • 139
2

Use a bit changed this solution - for testing use in operator - it loop only to matching like your requirement:

from numba import njit

@njit
def get_first_index_nb(A, k):
    for i in range(len(A)):
        if A[i] in k:
            return i
    return None

#pandas 0.24+
idx = get_first_index_nb(df.track.to_numpy(), ['V1', 'V2'])
#oldier pandas versions
#idx = get_first_index_nb(df.track.values, ['V1', 'V2'])
print (idx)

Solution with Series.idxmax if possible no values matching with if-else statement and Series.any, but it test all matching values:

m = df.track.isin(['V1', 'V2'])
idx = m.idxmax() if m.any() else None

Or:

idx = next(iter(df.index[df.track.isin(['V1', 'V2'])]), None)
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
1

Use Series.isin with DataFrame.index or Series.index

df[df.track.isin(['V1', 'V2'])].index[0]

or using callable

df.track.loc[lambda x: x.isin(['V1', 'V2'])].index[0]
ansev
  • 30,322
  • 5
  • 17
  • 31
1

You may use where and first_valid_index to handle case when V1 and V2 not found. In that case, first_valid_index returns None

idx = df.where(df.track.isin(['V1', 'V2'])).first_valid_index()
Andy L.
  • 24,909
  • 4
  • 17
  • 29
0

Just use your same code but with below changes.

From this

i = df[(df["track"] == "V1")  | (df["track"] == "V2")].iloc[0]

to

df[(df["track"] == "V1")  | (df["track"] == "V2")].head(1).iloc[0]
High-Octane
  • 1,104
  • 5
  • 19