Векторизованный способ поиска индекса ранее встречающегося элемента - PullRequest
1 голос
/ 28 февраля 2020

Допустим, у меня есть Pandas серия:

num = pd.Series([1,2,3,4,5,6,5,6,4,2,1,3])

Что я хочу сделать, это получить число, скажем, 5, и вернуть индекс, где он ранее имел место , Так что, если я использую элемент 5, я должен получить 4, так как элемент появляется в индексах 4 и 6. Теперь я хочу сделать это для всех элементов серии, и это легко сделать, используя a для l oop:

for idx,x in enumerate(num):
        idx_prev = num[num == x].idxmax()
        if(idx_prev < idx):
                return idx_prev

Однако этот процесс занимает слишком много времени для длинных серий из-за зацикливания. Есть ли способ реализовать то же самое, но в векторизованной форме? Вывод должен выглядеть примерно так:

[NaN,NaN,NaN,NaN,NaN,NaN,4,5,3,1,0,2]

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

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

num.index.to_series().groupby(num).shift()

Вывод:

0     NaN
1     NaN
2     NaN
3     NaN
4     NaN
5     NaN
6     4.0
7     5.0
8     3.0
9     1.0
10    0.0
11    2.0
dtype: float64
0 голосов
/ 28 февраля 2020

Можно продолжать работать в numpy.

Эквивалент [num[num == x].idxmax() for idx,x in enumerate(num)] с использованием numpy:

_, out = np.unique(num.values, return_inverse=True)

, который присваивает

array([0, 1, 2, 3, 4, 5, 4, 5, 3, 1, 0, 2], dtype=int64)

до out. Теперь вы можете назначить неправильные значения out для Nan s следующим образом:

out_series = pd.Series(out)
out_series[out >= np.arange(len(out))] = np.nan
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...