Подтвердить что ты не робот

Получить индекс строки фрейма pandas как целое число

Предположим, что простой фрейм данных, например

    A         B
0   1  0.810743
1   2  0.595866
2   3  0.154888
3   4  0.472721
4   5  0.894525
5   6  0.978174
6   7  0.859449
7   8  0.541247
8   9  0.232302
9  10  0.276566

Как я могу получить значение индекса строки, учитывая условие? Например: dfb = df[df['A']==5].index.values.astype(int) возвращает [4], но то, что я хотел бы получить, это просто 4. Это вызывает у меня проблемы позже в коде.

На основании некоторых условий я хочу иметь запись индексов, в которых выполняется это условие, а затем выбирать строки между ними.

Я пробовал

dfb = df[df['A']==5].index.values.astype(int)
dfbb = df[df['A']==8].index.values.astype(int)
df.loc[dfb:dfbb,'B']

для желаемого выхода

    A         B
4   5  0.894525
5   6  0.978174
6   7  0.859449

но я получаю TypeError: '[4]' is an invalid key

4b9b3361

Ответ 1

Чем проще add [0] - выбрать первое значение списка с одним элементом:

dfb = df[df['A']==5].index.values.astype(int)[0]
dfbb = df[df['A']==8].index.values.astype(int)[0]

dfb = int(df[df['A']==5].index[0])
dfbb = int(df[df['A']==8].index[0])

Но если это возможно, некоторые значения не совпадают, возникает ошибка, поскольку первое значение не существует.

Решение - использовать next с iter для получения параметров по умолчанию, если значения не совпадают:

dfb = next(iter(df[df['A']==5].index), 'no match')
print (dfb)
4

dfb = next(iter(df[df['A']==50].index), 'no match')
print (dfb)
no match

Тогда, похоже, нужно вычесть 1:

print (df.loc[dfb:dfbb-1,'B'])
4    0.894525
5    0.978174
6    0.859449
Name: B, dtype: float64

Другое решение с boolean indexing или query:

print (df[(df['A'] >= 5) & (df['A'] < 8)])
   A         B
4  5  0.894525
5  6  0.978174
6  7  0.859449

print (df.loc[(df['A'] >= 5) & (df['A'] < 8), 'B'])
4    0.894525
5    0.978174
6    0.859449
Name: B, dtype: float64

print (df.query('A >= 5 and A < 8'))
   A         B
4  5  0.894525
5  6  0.978174
6  7  0.859449

Ответ 2

Чтобы ответить на исходный вопрос о том, как получить индекс как целое число для нужного выбора, будет работать следующее:

df[df['A']==5].index.item()

Ответ 3

Характер желания включить строку, где A == 5 и все строки вверх, но не, включая строку, где A == 8 означает, что мы закончим использование iloc (loc включает в себя оба концы среза).

Чтобы получить индексные метки, мы используем idxmax. Это вернет первую позицию максимального значения. Я запускаю это в булевой последовательности, где A == 5 (тогда, когда A == 8), который возвращает значение индекса, когда A == 5 сначала происходит (то же самое для A == 8).

Затем я использую searchsorted, чтобы найти порядковое положение, где встречается метка индекса (которая была найдена выше). Это то, что я использую в iloc.

i5, i8 = df.index.searchsorted([df.A.eq(5).idxmax(), df.A.eq(8).idxmax()])
df.iloc[i5:i8]

введите описание изображения здесь


numpy

вы можете еще больше улучшить это, используя базовые объекты numpy аналогичные функции numpy. Я включил его в удобную функцию.

def find_between(df, col, v1, v2):
    vals = df[col].values
    mx1, mx2 = (vals == v1).argmax(), (vals == v2).argmax()
    idx = df.index.values
    i1, i2 = idx.searchsorted([mx1, mx2])
    return df.iloc[i1:i2]

find_between(df, 'A', 5, 8)

введите описание изображения здесь


времени
введите описание изображения здесь