Хорошие способы обернуть индексы для нарезки в кадре данных панд - PullRequest
0 голосов
/ 15 ноября 2018

Я хочу разрезать фрейм данных по строкам или столбцам, используя iloc, при этом обтекание индексов выходит за пределы. Вот пример:

import pandas as pd
df = pd.DataFrame([[1,2,3], [4,5,6], [7,8,9]],columns=['a', 'b', 'c'])
#Slice the rows from 2 to 4, which the dataframe only have 3 rows
print(df.iloc[2:4,:])

Фрейм данных:

    a   b   c  
0   1   2   3  
1   4   5   6  
2   7   8   9  

Вывод будет:

    a   b   c
2   7   8   9

Но я хочу обернуть вокруг вне указанного индекса, который выглядит как:

    a   b   c
2   7   8   9
0   1   2   3

В numpy можно использовать numpy.take, чтобы обернуть вокруг ограниченного индекса для нарезки. ( Ссылка NumPy Take )

import numpy as np
array = np.array([[1,2,3], [4,5,6], [7,8,9]])
print(array.take(range(2,4) , axis = 0, mode='wrap'))

Вывод:

 [[7 8 9]
 [1 2 3]]

Возможное решение для упаковки в pandas заключается в использовании numpy.take:

import pandas as pd
import numpy as np
df = pd.DataFrame([[1,2,3], [4,5,6], [7,8,9]],columns=['a', 'b', 'c'])
# Get the integer indices of the dataframe
row_indices = np.arange(df.shape[0])
# Wrap the slice explicitly
wrap_slice = row_indices.take(range(2,4),axis = 0, mode='wrap')
print(df.iloc[wrap_slice, :])

Выводом будет вывод, который я хочу:

   a  b  c
2  7  8  9
0  1  2  3

Я посмотрел в pandas.DataFrame.take и режима "wrap" нет. ( Панды берут ссылку ). Какой хороший и простой способ решить эту проблему? Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Вы можете использовать деление остатка

import numpy as np

start_id = 2
end_id = 4
idx = np.arange(start_id, end_id, 1)%len(df)

df.iloc[idx]
#   a  b  c
#2  7  8  9
#0  1  2  3

Этот метод фактически позволяет вам циклически повторяться:

start_id = 2
end_id = 10
idx = np.arange(start_id, end_id, 1)%len(df)

df.iloc[idx]
#   a  b  c
#2  7  8  9
#0  1  2  3
#1  4  5  6
#2  7  8  9
#0  1  2  3
#1  4  5  6
#2  7  8  9
#0  1  2  3
0 голосов
/ 15 ноября 2018

Давайте попробуем использовать np.roll:

df.reindex(np.roll(df.index, shift=-2)[0:2])

Выход:

   a  b  c
2  7  8  9
0  1  2  3

И, чтобы сделать его немного более общим:

startidx = 2
endidx = 4

df.iloc[np.roll(df.index, shift=-1*startidx)[0:endidx-startidx]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...