Получить индекс строки фрейма 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
Ответы
Ответ 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)
![введите описание изображения здесь]()
времени
![введите описание изображения здесь]()