Следующее использует numpy (неявным образом расширяя векторы до матрицы с использованием широковещания) и работает намного быстрее, чем предложенный вами ответ:
df['res'] = (df['col2'].values.reshape(1,-1) < df['col1'].values.reshape(-1,1)).sum(axis=1)
(в тесте df с 10k строками, на моей машине этозанимает 0,3 с вместо 8 с).Однако он использует квадратичную память в количестве строк, поэтому, если ваш df имеет миллионы строк, это не очень хорошо ...
[EDIT] Существует решение в O (n * log (n)) (nчисло строк) во времени и пространстве, которое, вероятно, близко к оптимальному (выше указано O (n ^ 2) в обеих, реализация его в C будет O (n ^ 2) во времени, но только O (n)в пространстве), но я не написал код, поскольку он становится утомительным, особенно для обработки случаев равенства и т. д. Псевдокод выглядит следующим образом:
- Сортировка col1 и получение его индексов.Скажем, это дает вам словарь исходного индекса -> отсортированный индекс.
- Сортируйте сопоставленный вектор [col1, col2] и возьмите индексы.Это дает другое отображение, оригинальный индекс -> индекс сортировки.
- Ответ должен быть разностью второго вектора минус первый.
[EDIT2]: Реализация его была на самом деле оченьпроще, чем я думал, это просто:
idx1 = np.argsort(np.argsort(df['col1'], kind='mergesort'), kind='mergesort')
idx2 = np.argsort(np.argsort(np.concatenate((df['col1'], df['col2'])), kind='mergesort'), kind='mergesort')[:len(idx1)]
df['res'] = idx2-idx1
Как уже говорилось, это всего лишь O (n * log (n)) как во времени, так и в пространстве, поэтому даже при большом значении df это занимает очень мало времени (0,1 с для строк по 100 тыс., 1,5 с для строк по 1 млн.) И очень мало дополнительного пространства.
Двойной аргумент argsort обусловлен соглашением о простой сортировке, np.argsort не дает индекс элемента в отсортированном вектореа точнее индекс такой, что x [idx] отсортирован.Небольшой трюк, состоящий в том, чтобы дважды выполнить argsort, дает положение исходного элемента в отсортированном векторе.Я добавил kind = 'mergesort', чтобы использовать стабильную сортировку, это само по себе довольно бесполезно, но должно исправить проблемы, если значение появляется как в col1, так и в col2 (потому что мы хотим считать, когда col2