переупорядочить подмножество строк в pandas фрейме данных (переиндексировать) - PullRequest
2 голосов
/ 09 апреля 2020

с использованием

import pandas as pd
import numpy as np

Для данного кадра данных

df = pd.DataFrame(np.array([[1, 2, 3],
                             [4, 5, 6],
                             [7, 8, 9],
                             [10, 11, 12],
                             [13, 14, 15],
                             [16, 17, 18],
                             [19, 20, 21]
                             ]),
                   columns=['a', 'b', 'c'])


Out[1]: 
    a   b   c
0   1   2   3
1   4   5   6
2   7   8   9
3  10  11  12
4  13  14  15
5  16  17  18
6  19  20  21

Я хочу изменить порядок и вернуть на место строки с 2 по 5,

2   7   8   9
3  10  11  12
4  13  14  15
5  16  17  18

Если порядок внутри подмножества [2,0,1,3], то желаемый результат будет

Out[2]: 
    a   b   c
0   1   2   3
1   4   5   6
4  13  14  15
2   7   8   9
3  10  11  12
5  16  17  18
6  19  20  21

(мне нужно сделать это для разных подмножеств в разных порядках. Это только пример.)

Моя попытка

Мое подмножество

idx = [2,3,4,5]
idx2 = np.array(idx)

Новый порядок

i = [2,0,1,3]

Если я это сделаю,

df.iloc[idx].reindex(idx2[i])

Я получу Подмножество в правильном порядке, тогда я подумал, что следующее должно работать,

df.iloc[idx] = df.iloc[idx].reindex(idx2[i]).reset_index(drop=True)

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

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Поскольку индекс pandas не является изменяемым, вы можете сделать его массивом, изменить нужную часть массива и reindex:

idx = [2,3,4,5]
i = [2,0,1,3]

# pandas index to array
arr_idx = df.index.to_numpy()
# modify the order of the array
arr_idx[idx] = arr_idx[idx][i]
# reindex
df = df.reindex(arr_idx)

print (df)
    a   b   c
0   1   2   3
1   4   5   6
4   7   8   9
2  10  11  12
3  13  14  15
5  16  17  18
6  19  20  21
2 голосов
/ 09 апреля 2020

Вы можете использовать переупорядочение индекса на основе списка ввода, а затем разделить индекс после фильтрации переупорядоченного индекса из исходного индекса на 2 группы, а затем использовать np.r_ с df.iloc[] для достичь результата:

import more_itertools as mit
i = [2,0,1,3] #input list

rearranged_idx = df.index[2:6][i] #since you're interested in rows 2 to 5
i = [list(i) for i in 
     mit.consecutive_groups(df.index.difference(rearranged_idx,sort=False))]
# [[0, 1], [6]]
out = df.iloc[np.r_[i[0],rearranged_idx,i[-1]]]

    a   b   c
0   1   2   3
1   4   5   6
4  13  14  15
2   7   8   9
3  10  11  12
5  16  17  18
6  19  20  21
...