Pandas: Какой самый эффективный способ перебирать Pandas DataFrame строка за строкой?

Созданный на 12 июн. 2015  ·  6Комментарии  ·  Источник: pandas-dev/pandas

Я пробовал функцию df.iterrows() но ее производительность ужасна. Что неудивительно, учитывая, что iterrows() возвращает Series с полной схемой и метаданными, а не только значениями (которые мне нужны).

Второй метод, который я пробовал, - это for row in df.values , который значительно быстрее. Однако недавно я понял, что df.values не является внутренним хранилищем данных DataFrame, потому что df.values преобразует все dtypes в общий dtype . Например, один из моих столбцов имеет dtype int64 но dtype для df.values равен float64 . Поэтому я подозреваю, что df.values самом деле создает еще одну копию внутренних данных.

Кроме того, еще одно требование состоит в том, что итерация строки должна возвращать список значений, сохраняющих исходный dtype данных.

Usage Question

Самый полезный комментарий

Я думаю, что df.itertuples() - это то, что вы ищете - это намного быстрее, чем iterrows:

In [10]: x = pd.DataFrame({'x': range(10000)})

In [11]: %timeit list(x.iterrows())
1 loops, best of 3: 383 ms per loop

In [12]: %timeit list(x.itertuples())
1000 loops, best of 3: 1.39 ms per loop

Все 6 Комментарий

В Python перебор строк будет (намного) медленнее, чем выполнение векторизованных операций.

Типы преобразуются в вашем втором методе, потому что так работают массивы numpy (что и есть df.values ). DataFrames основаны на столбцах, поэтому у вас может быть один DataFrame с несколькими dtypes. Как только вы выполняете итерацию по строкам, все должно быть приведено к более общему типу, который содержит все. В вашем случае целые числа идут в float64 .

Если вы опишете свою проблему на минимальном рабочем примере, мы сможем помочь вам векторизовать ее. Вам также может повезти в StackOverflow с тегом pandas.

По сути, я хочу сделать следующее:

row_handler = RowHandler(sample_df)  # learn how to handle row from sample data
transformed_data = []
for row in df.values:
    transformed_data.append(row_handler.handle(row))
return transformed_data

Я не владею классом RowHandler и, следовательно, могу работать только построчно.

Другой похожий пример - машинное обучение, где у вас может быть модель, которая имеет API прогнозирования только на уровне строки.

Все еще слишком расплывчато, чтобы быть полезным. Но если RowHandler действительно выходит из-под вашего контроля, вам не повезло. FWIW: все API-интерфейсы scikit-learn работают с массивами (то есть с несколькими строками).

Не понимаю, как это может быть яснее. Да, RowHandler вне моего контроля. Что вы имеете в виду под невезением? Мой вопрос заключается в наиболее эффективном способе перебора строк, сохраняя при этом dtype каждого элемента. Вы предлагаете df.iterrows() или что-то еще?

sklearn - это исключение, а не норма, которое изначально работает с DataFrame PD. Не во многих библиотеках машинного обучения есть API, которые работают с DataFrame .

Я думаю, что df.itertuples() - это то, что вы ищете - это намного быстрее, чем iterrows:

In [10]: x = pd.DataFrame({'x': range(10000)})

In [11]: %timeit list(x.iterrows())
1 loops, best of 3: 383 ms per loop

In [12]: %timeit list(x.itertuples())
1000 loops, best of 3: 1.39 ms per loop

Спасибо @shoyer! Это то что мне нужно.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги