Каков наиболее эффективный способ прокрутки данных с помощью панд?

Я хочу последовательно выполнять свои собственные сложные операции с финансовыми данными в dataframes.

Например, я использую следующий файл MSFT CSV, взятый из Yahoo Finance :

Date,Open,High,Low,Close,Volume,Adj Close 2011-10-19,27.37,27.47,27.01,27.13,42880000,27.13 2011-10-18,26.94,27.40,26.80,27.31,52487900,27.31 2011-10-17,27.11,27.42,26.85,26.98,39433400,26.98 2011-10-14,27.31,27.50,27.02,27.27,50947700,27.27 .... 

Затем я делаю следующее:

 #!/usr/bin/env python from pandas import * df = read_csv('table.csv') for i, row in enumerate(df.values): date = df.index[i] open, high, low, close, adjclose = row #now perform analysis on open/close based on date, etc.. 

Это самый эффективный способ? Учитывая сосредоточенность на скорости в пандах, я бы предположил, что должна быть какая-то специальная функция для итерации значений таким образом, чтобы один из них также извлекал индекс (возможно, с помощью генератора для эффективной памяти)? df.iteritems сожалению, df.iteritems выполняет только df.iteritems столбца по столбцу.

  • Как сделать экспоненциацию в python?
  • Python: Что-то делать для любого метода класса?
  • Пример Oauth для Google API с использованием Python / Django
  • SQLAlchemy Column to Row Transformation и наоборот - возможно ли это?
  • thread.start_new_thread vs threading.Thread.start
  • Какова практическая разница между xml, json, rss и атомом при взаимодействии с Twitter?
  • Как включить изображение или картинку в блокнот jupyter
  • Как читать и хранить значения из текстового файла в словаре.
  • 7 Solutions collect form web for “Каков наиболее эффективный способ прокрутки данных с помощью панд?”

    Новые версии pandas теперь включают встроенную функцию для итерации по строкам.

     for index, row in df.iterrows(): # do some logic here 

    Или, если вы хотите быстрее использовать itertuples()

    Но, предложение unutbu использовать функции numpy, чтобы избежать итерации по строкам, будет производить самый быстрый код.

    Pandas базируется на массивах NumPy. Ключом к ускорению работы с массивами NumPy является выполнение ваших операций по всему массиву сразу, никогда не по очереди или по каждому элементу.

    Например, если close – это 1-мерный массив, и вы хотите, чтобы процентное изменение дня за днем ​​изменилось,

     pct_change = close[1:]/close[:-1] 

    Это вычисляет весь массив процентных изменений как один оператор, а не

     pct_change = [] for row in close: pct_change.append(...) 

    Поэтому старайтесь избегать цикла Python for i, row in enumerate(...) целиком и думать о том, как выполнять ваши вычисления с операциями по всему массиву (или файловому кадру) в целом, а не по строкам.

    Вы можете прокручивать строки путем транспонирования, а затем вызывать iteritems:

     for date, row in df.T.iteritems(): # do some logic here 

    В этом случае я не уверен в эффективности. Чтобы получить наилучшую производительность в итеративном алгоритме, вы можете изучить его в Cython , чтобы вы могли сделать что-то вроде:

     def my_algo(ndarray[object] dates, ndarray[float64_t] open, ndarray[float64_t] low, ndarray[float64_t] high, ndarray[float64_t] close, ndarray[float64_t] volume): cdef: Py_ssize_t i, n float64_t foo n = len(dates) for i from 0 <= i < n: foo = close[i] - open[i] # will be extremely fast 

    Я бы рекомендовал сначала написать алгоритм в чистом Python, убедиться, что он работает, и посмотреть, как быстро это происходит – если это не так быстро, конвертировать вещи в Cython, как это, с минимальной работой, чтобы получить что-то примерно так же быстро, как ручная кодировка C / C ++.

    Как и раньше, объект pandas наиболее эффективен при обработке всего массива сразу. Тем не менее для тех, кто действительно нуждается в прокрутке pandas DataFrame для выполнения чего-то, как и я, я нашел по крайней мере три способа сделать это. Я сделал короткий тест, чтобы узнать, какой из трех является наименее трудоемким.

     t = pd.DataFrame({'a': range(0, 10000), 'b': range(10000, 20000)}) B = [] C = [] A = time.time() for i,r in t.iterrows(): C.append((r['a'], r['b'])) B.append(time.time()-A) C = [] A = time.time() for ir in t.itertuples(): C.append((ir[1], ir[2])) B.append(time.time()-A) C = [] A = time.time() for r in zip(t['a'], t['b']): C.append((r[0], r[1])) B.append(time.time()-A) print B 

    Результат:

     [0.5639059543609619, 0.017839908599853516, 0.005645036697387695] 

    Это, вероятно, не самый лучший способ измерить потребление времени, но это быстро для меня.

    Вот некоторые плюсы и минусы ИМХО:

    • .iterrows (): возвращает индекс и элементы строки в отдельных переменных, но значительно медленнее
    • .itertuples (): быстрее, чем .iterrows (), но возвращает индекс вместе с элементами строки, ir [0] – индекс
    • zip: самый быстрый, но не доступ к индексу строки

    Я проверил iterrows заметив ответ Ника Кроуфорда , но обнаружил, что он дает (индекс, серию) кортежи. Не уверен, что будет работать лучше всего для вас, но в итоге я использовал метод itertuples для своей проблемы, который дает (index, row_value1 …) кортежи.

    Также есть iterkv , который выполняет итерации через (столбцы, ряды) кортежей.

    Так же, как небольшое дополнение, вы также можете подать заявку, если у вас есть сложная функция, которую вы применяете к одному столбцу:

    http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.apply.html

     df[b] = df[a].apply(lambda col: do stuff with col here) 

    Другое предложение состояло бы в том, чтобы объединить groupby с векторизованными вычислениями, если подмножества общих характеристик строк позволили вам это сделать.

    Python - лучший язык программирования в мире.