Pandas: PandasのDataFrameを行ごとに繰り返す最も効率的な方法は何ですか?

作成日 2015年06月12日  ·  6コメント  ·  ソース: pandas-dev/pandas

関数df.iterrows()を試しましたが、そのパフォーマンスはひどいものです。 iterrows()が値だけでなく完全なスキーマとメタデータを含むSeriesを返すことを考えると、これは驚くべきことではありません(私が必要とするすべてのもの)。

私が試した2番目の方法はfor row in df.values 、これは非常に高速です。 ただし、最近、 df.valuesがDataFrameの内部データストレージではないことに気付きました。これは、 df.valuesがすべてのdtypesを共通のdtype変換するためです。 たとえば、私の列の1つにdtype int64がありますが、 df.valuesのdtypeはすべて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では、行の反復処理は、ベクトル化された操作を実行するよりも(かなり)遅くなります。

2番目のメソッドで型が変換されているのは、それがnumpy配列df.valuesとは何か)の仕組みだからです。 DataFrameは列ベースであるため、複数のdtypeを持つ単一のDataFrameを持つことができます。 行ごとに繰り返し処理したら、すべてを保持するより一般的なタイプにすべてをアップキャストする必要があります。 あなたの場合、intはfloat64行きます。

最小限の実用的な例で問題を説明すると、ベクトル化を支援できる可能性があります。 また、pandasタグを使用してStackOverflowで運が良かったかもしれません。

基本的に、私は次のことをしたいと思います。

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クラスを所有していないため、行ごとにしか操作できません。

もう1つの同様の例は機械学習で、行レベルでのみ予測APIを持つモデルがある場合があります。

まだ少し曖昧すぎて役に立ちません。 しかし、 RowHandlerが本当にあなたのコントロールの外にあるなら、あなたは運が悪いでしょう。 FWIW scikit-learnのすべてのAPIは配列(つまり複数の行)で動作します。

どうすればもっと明確にできるのかわかりません。 はい、 RowHandlerは私の手に負えません。 運が悪いとはどういう意味ですか? 私の質問は、各要素のdtypeをそのままに保ちながら、行を反復処理する最も効率的な方法です。 df.iterrows() 、または何か他のものを提案していますか?

sklearnは例外であり、PDのDataFrameネイティブに動作する標準ではありません。 DataFrameで動作するAPIを備えた機械学習ライブラリは多くありません。

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 評価