Быстрый способ найти предыдущий экземпляр значения в панде Dataframe или массив Numpy? - PullRequest
3 голосов
/ 13 октября 2019

У меня большой набор данных (количество строк в миллионах), который я считал в панде DataFrame с именем datafile .

Каждая строка имеет идентификационный номер заказа - это не уникально. Так что мой файл данных выглядит примерно так

Price   Qty           OrderId

26690  3000  1213772

26700  3000  1215673

26705  6000  1216656

26700  3000  1213772

26710  3000  1215673

Теперь, что я хочу, для каждой строки - получить OrderID, найти предыдущее вхождение этого OrderID в DataFrame и получитьсоответствующей цены и заполните ее в новом столбце «Prev_Price». Если предыдущее вхождение не найдено, оставьте значение 0. Итак, мой вывод должен выглядеть следующим образом

Price   Qty           OrderId  Prev_Price

26690  3000  1213772 0

26700  3000  1215673 0

26705  6000  1216656 0

26700  3000  1213772 26690

26710  3000  1215673 26700

Я попытался использовать numpy и написал эту функцию

def getPrevPrice_np(x):
    try:
        return list(datanp[np.where(datanp[0:x,2]==datanp[x,2])][:,0])[-1]
    except:
        return 0

, которую яподать заявку вот так

datanp = datafile.values
datafile['Prev_Price'] = pd.Series(datafile.index).apply(getPrevPrice_np)

Но это все еще довольно медленно для моего требования - какой самый быстрый способ реализовать это?

1 Ответ

3 голосов
/ 13 октября 2019

Это быстрее:

datafile['Prev_Price'] = datafile.groupby('OrderId')['Price'].shift(fill_value=0)

Возвращает:

   Price   Qty  OrderId  Prev_Price
0  26690  3000  1213772           0
1  26700  3000  1215673           0
2  26705  6000  1216656           0
3  26700  3000  1213772       26690
4  26710  3000  1215673       26700

Теперь на коротком фрейме данных, таком как тот, который вы опубликовали, этот метод на самом деле медленнее.
Но ясделал пару тестов с большими фреймами данных:

  • на фрейме данных из 100000 (ста тысяч) строк, это быстрее в 3 раза, примерно.
  • на фрейме данных1000000 (один миллион) строк это все еще занимает ~ 1,5 секунды на моем компьютере, я не измерял время выполнения вашего метода (занимает слишком много времени и я уничтожил процесс).

Примечание: fill_value является допустимым аргументом pandas.DataFrame.shift, поскольку pandas 0.24.0. Для более старой версии не передавайте аргумент и замените значения NaN позже, используя datafile.fillna(0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...