paint-brush
SQL の代わりに Pandas を教えているのはなぜですか?by@vladpublish
19,433
19,433

SQL の代わりに Pandas を教えているのはなぜですか?

Vlad Gheorghe2m2022/05/20
Read on Terminal Reader
Read this story w/o Javascript

ほとんどのデータ ブートキャンプのカリキュラムでは、(Jupyter ノートブックと並んで) pandas に多額の投資が行われていますが、SQL はせいぜい後付けです。彼らは反対のことをすべきです。 Pandas は、複雑さ、非効率性、特異性、および混乱の可能性という点で、かなりのオーバーヘッドをもたらします。 pandas の方が優れている点もありますが、全体として、純粋な分析に関しては、SQL に勝るものはありません。

People Mentioned

Mention Thumbnail

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coins Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - SQL の代わりに Pandas を教えているのはなぜですか?
Vlad Gheorghe HackerNoon profile picture


UnsplashのPedro Gonzalezによる写真


むかしむかし、データサイエンスを学びたいと熱望している学生がいました。


彼は何をすべきか人々に尋ねたところ、彼らはパンダを学ぶように彼に言いました.彼はウェブでデータ コースを探しましたが、それらはすべてパンダを特集していました。そこで学生はパンダを学び、アカデミアに就職しました。そこでは誰もがパンダを扱っていました。


そのため、彼は睡眠中にデータフレームをスライスできるようになるまで、何ヶ月にもわたってパンダで苦労しました。終わった後、彼はデータ ブートキャンプに参加しました。見よ、彼らはパンダを教えていました。彼が終わったとき、ブートキャンプはパンダを教えるために彼を雇いました。


そして、学生が最初の会社に入った時が来ました。彼のマスターは、彼にデータを処理することを望んでいました。


「私はパンダを使います」と学生は言いました。


「なんてこった!」マスターは言った。 「ここでは S-Q-L を使用します」と彼は反論し、棒で一撃して各文字を強調しました。


「しかし...しかし...冗長...醜い...機能の欠如...無限のネスト...そして、結合、結合は恐ろしいです!...」


「森が見えないなら、木に触れてはいけない」と主人は言い、頭を殴りました。


その学生は悟りを開いた。


またはそう彼は思った。実際、マスターの打撃は彼をひどく気絶させたので、彼の判断力は一時的に損なわれました.


数か月後、痛みを伴う引きこもりの後、学生は SQL を理解するようになりました。それ以来、彼は再びパンダを使う必要性を感じなくなり、マスターは二度と彼に打撃を与えることはありませんでした.

SQL >> パンダ


上記の公案は自伝的なものですが、私の監督者は誰も私を殴ったことはありません (殴るはずの時でさえ)。


始めた頃とほとんど変わりません。ほとんどのデータ ブートキャンプのカリキュラムでは、(Jupyter ノートブックと並んで) pandas に多額の投資が行われていますが、SQL はせいぜい後付けです。


Udemy で「データ サイエンス」を検索すると、Python (必然的に pandas が含まれます) と R、場合によっては Scala に言及しているトップ コースが表示されます。それらの中で SQL に言及しているものはほとんどありません。


これは、価値の観点からも、教育学的な観点からも、悪いことだと思います。

価値の問題

標準的な分析を行っている場合、SQL は pandas よりも優れたツールです。それはよりシンプルで、より明確で、より強力で効率的です。また、理解、共有、再現が容易になります。それが何十年にもわたってデータ分析の共通語であったのには理由があります。


SQL を犠牲にして Pandas に集中している場合は、より優れた効果的なデータ プラクティショナーになる機会を逃しています。


もちろん、pandas の方が優れている点もあり、記事の最後で簡単に説明します。しかし全体として、純粋な分析に関して言えば、SQL に勝るものはありません。


多くの人は、pandas が複雑さ、非効率性、特異性、および混乱の可能性という点で大きなオーバーヘッドをもたらすことに気付かないことがよくあります。

学習の問題


http://stream1.gifsoup.com/view2/1321405/angry-panda-o.gif


パンダを過度に強調することは、データを学ぶ学生を傷つけるのではないかと思います。私の経験では、より多くの pandas を行うと反学習になるポイントがあります。つまり、時間の経過とともに単純に混乱します。


特に新入生は、彼らを混乱させ、盲目的な暗記で補う奇妙な問題を経験します.


また、テーブル操作を使用できるときに行をループするなど、後であきらめるのが難しい悪い習慣も身に付けます。タイプが混在する列を作成する。データを CSV に保存します。その場でデータを変更します。同じデータフレームの複数のコピーとスライスでメモリを詰まらせる...私は続けることができました。


これには、Python が非常に寛容な言語であるため、ユーザーに悪いことをしないという負担がかかります (混合型の pandas Seriesなど)。その一部は、pandas が (必ずしも推奨するわけではありませんが) 命令型アプローチを受け入れるという事実に由来しています。


たとえば、学生が 2 つのテーブルのデータを結合したい場合、このアルゴリズムの使用を妨げるものは何もありません。


  1. table1をループする

  2. table1行ごとに、ルックアップのためにすべてのtable2をスキャンします。

  3. table2のデータからtable1の行を更新します。


はい、これは明らかに非常に悪いです。しかし、初心者はそれ以上のことを知りません。

対照的に、SQL の宣言型アプローチにより、悪いことを行うのが難しくなります。


宣言型プログラミングでは、ユーザーは結果を生成する方法ではなく、見たい結果の観点から考える必要があります。これにより、問題や奇妙なバグに常に悩まされるのではなく、分析の背後にあるロジックに集中するために必要なスペースが得られます。


また、SQL は学生にテーブル (つまりリレーショナル モデル) と列レベルの操作で考えるように強制します。


最後に、SQL を学習すると、その普遍性と移植性により、投資収益率が向上します。

免責事項

パンダは嫌いじゃない。これは 2 年間、私の基本的な分析ツールでしたが、今でも個人的なプロジェクトに使用しています。人々がそれを学んでいるのを見るのはうれしいです。


しかし、私は全体像を見ようとしています。 SQL を犠牲にしてパンダを過度に強調することは、良いことよりも悪いことだと思います。特に、適切なGROUP BYを実行する前にMultiIndexについて学んでいる初心者の場合。

見込み

次のセクションでは、pandas の最も奇妙な側面をいくつか分析し、SQL と直接比較します。


繰り返しますが、目標は pandas を下に置くことではなく、自由に使えるツールに対する読者の視点を広げることです。


掘り下げてみましょう。


 SELECT * FROM opinionated_comparison WHERE sql > pandas

比較

https://www.reddit.com/r/funny/comments/5ysm1t/pandas_on_slide/


列の選択

単一のステートメントで、SQL のSELECTを使用すると、次のことができます。


  1. 必要な列と、それらが返される順序を選択します。


  2. 既存の列の組み合わせと変換に基づいて、新しい列を作成します。


  3. 列の名前を変更します。


この例では、1 つを除くすべての列を選択し、他の 2 つの列の線形結合に基づいて新しい列を作成します。


 SELECT * EXCEPT (first_name), equity_comp / total_comp * 100 AS percent_equity FROM salaries


pandas の列選択では、列の選択と順序付けのみが可能です。一部の名前を変更したり変換したりする場合は、複数のステートメントが必要であり、多くの人がデータをその場で変換するというエラーに陥ります (以下の不変性を参照)。


初心者は、単一の列を選択するには 1 セットの括弧 ( df[”first_name”] ) が必要であり、複数の列を選択するには 2 組の括弧 ( df[[”first_name”, "last_name"]] ) が必要であるため、混乱します。


ここで pandas に関して私が抱えている最大の問題は、ドット表記です: df.first_nameのように列を選択できるという事実です。


これは、括弧や引用符を使用するよりもはるかに簡単であるため、人々はまったくの怠惰からそれを好むことになります.それが少なくとも私に起こったことです。ドット表記が悪いことだとわかっていても、私はまだドット表記を自動的に使用しています。


countまたはshapeまたはdiffと呼ばれる列、またはデータフレームの他の多くの標準属性のいずれかがある場合に問題が発生します (それらはすべてdir(df)で表示できます)。


ドット表記でそれらにアクセスしようとすると、列ではなく属性が取得され、コードが壊れます。


そのため、pandas には列を選択する 3 つの方法があります。1 つの列を取得するための 2 つ (そのうちの 1 つは悪いが、より魅力的です!) と、複数の列を選択するための 3 つ目の方法です。

行の選択

SQL では、特定の行を選択するには、 WHEREステートメントを使用するだけです (以下のフィルタリングを参照)。


Pandas で行を選択するのは... 複雑です。複雑さを確認するには、ユーザー スタート ガイドを確認してください。または、典型的な30 分間のチュートリアルを詳しく調べてください。


例を 1 つだけ挙げます。すべての DataFrame にはIndexがあります。デフォルトのインデックスは整数のシーケンスです: [0,1,2,3,4,5...]


当然のことながら、ほとんどの人は、インデックスが行のカーディナリティを表していると想定しています。実際には、数値は単なるカテゴリ ラベルです。 ['x', 'z', 'a']ようなランダムな文字でもかまいません。暗示されるカーディナリティはありません。


インデックスで行を取得するには、 df.locを使用します。ただし、行のカーディナリティで選択するには、 df.ilocを使用します。デフォルトのインデックスでは、これら 2 つのメソッドは同じ結果を返します。


いつでもインデックスが[7, 2, 2, 'c', True, None]ような完全にランダムなものに変更される可能性があるため、これは混乱を招くだけです。はい、これはすべて許可されています。また、それを防ぐための制約はありません (以下の制約を参照してください)。


インデックスが行のカーディナリティを表すと仮定してコードを記述したと想像してください。今:


  • df.loc[7]は最初の行を返します
  • df.loc[2]は、行ではなくデータフレーム スライスを返します (インデックス内で複数回発生するため)。
  • df.loc[None]は実際の行を返します!

私が泣いているのではなく、あなたが泣いているのです。



はい:同じメソッドで、インデックスの構成方法に応じて、スカラー値、行、またはデータフレーム スライスを返すことができます。パンダのドキュメントは、この狂気を認めています。


インデックス作成などの他の方法では、非常に驚くべき結果が得られる場合があります。通常、スカラーでインデックスを作成すると、次元が削減されます。スカラーでDataFrameをスライスすると、 Seriesが返されます。 Seriesをスカラーでスライスすると、スカラーが返されます。しかし、[index] の重複では、そうではありません。



インデックスに重複が含まれないようにするための制約はありません。これが私を引き起こした頭痛の数をあなたに伝えることはできません.


(これまでに説明したすべての選択方法に加えて、pandas には単一の値用のdf.atdf.iatもあります。混乱を避けるために覚えておくべきもう 1 つのことです。)

フィルタリング

SQL では、フィルタリングは簡単です。 WHEREを記述し、必要な数のステートメントを挿入し、それらを論理演算子で連結します。ブラケットを使用すると、式の構造化をより細かく制御できます。


たとえば、次のクエリは、2 人とも 30 歳以上で、勤続年数が 5 年以上、または株式報酬が 50 年未満の 2 つの条件の少なくとも 1 つを満たす人をフィルター処理します。


 SELECT * from salaries WHERE age > 30 AND (tenure > 5 OR equity_comp < 50)


これはパンダではどのように見えますか?


 new_df = df[(df["age"] > 30) & ((df["tenure"] > 5) | (df["equity_comp"] < 50))]


うーん。これを初心者に説明して楽しんでください。


確かに、あまりにも醜いので、おそらくこのようには書かないでしょう。複数のステートメントでフィルタリングを実行すると、コード、変数、および繰り返しの行が増えることになります。


Pandas フィルターは、ブール インデックスと呼ばれる方法に基づいています。すべてのフィルタリング操作は、次の 2 つの手順で行われます。


  1. Series (列オブジェクト) を取得し、各要素をブール値テストで実行します。したがって、ブール値 (true または false) で構成される新しいSeriesに変換します。


  2. この列でデータフレームを選択すると、ブール値Seriesに false 値が含まれる行が除外されます。


ここに隠れた前提があることに気付きましたか?フィルタリングに使用されるSeriesとフィルタリングされるデータフレームは、同じインデックスを同じ順序で共有する必要があります。これは常に保証されるわけではありません。


実際には、ブール値のインデックス付けは、フィルタリングするときに、常にデータフレーム変数を繰り返さなければならないことを意味します (例: salaries[salaries["cash_comp"] > 20] 。たくさんのコードを書いているとき、これは非常に面倒です!上記の例を参照してください。データフレーム変数は 4 回参照されています。


ブール値のインデックス付けは初心者にとって理解しにくいということも経験から言えます。根底にあるメカニズムをまったく理解できない人もいます。彼らはコーディングパターンを覚えているだけです。


( df.query()メソッドは、フィルタリングのためのより良い方法を提供しているようです。)

グループ化

ここには大きな不満はありません。しかし、SQL は間違いなく英語に近いです。これら 2 つは同等です。


 SELECT AVG(cash_comp), SUM(tenure) FROM salaries GROUP BY department
 grouped_df = df.groupby('department').agg({"cash_comp": np.mean, "tenure": np.sum})

ジョイン

SQL には 1 種類の結合があります。それはJOINと呼ばれます。もちろん、左/右、内側/外側のどちらでもかまいませんが、使用方法は非常に簡単です。


Pandas には、 joinmergeの 2 つのメソッドがあります。なぜ2つ必要なのか理解できませんでした。 joinはインデックスで動作するはずであり、 mergeは任意の列で動作するはずです。


しかし、ドキュメント [ 1 ][ 2 ] を見ると、それぞれがインデックスと列の両方をサポートしているようです。私は混乱しています。 (確信が持てない場合は、常に結合を選択することをお勧めします。 mergejoinは従来の方法に近いからです。)


SQL を使用すると、次のような一連の論理条件に基づいて JOIN を実行するのが非常に簡単になります。たとえば、ロールごとに参加しますが、ロンドンの給与がワシントンの給与よりも高い場合や、その人の在職期間が長い場合に限られます。


 SELECT * FROM london_hq lhq JOIN washington_hq whq ON lhq.role = whq.role AND (lhq.salary > whq.salary OR lhq.tenure > whq.tenure)


私の知る限り、これはパンダでは不可能です。結合 (またはマージ) するときは、等価条件のみを使用できます。


したがって、最初にroleで JOIN を実行し、各列のオリジンを追跡してから、結果をフィルタリングする必要があります。


ただし、これらの条件は当然 JOIN に属しており、等値比較を使用しないこととの関連性が低いわけではないと私は主張します。

タイピング

SQL の主な利点の 1 つは、すべての列に適切に定義された型があることです。さらに、列に型を混在させることはできません。これにより、長期的には多くのバグや頭痛の種が節約されます。


pandas にデータをロードすると、ほとんどの列はobjectとして自動的に型指定されます。これは、次の 3 つのいずれかを意味します。


  1. 列には文字列のみが含まれています

  2. 列には、プリミティブ データ型ではない Python オブジェクト (リストや辞書など) が含まれています。

  3. 列に混合型が含まれています


objectのデータ型を見ると、どちらが当てはまるかわかりません。これは非常に面倒です。


SQL とは異なり、pandas では型が混在するデータを読み込むことができます。それらは単純にobjectとして型付けされます。


Pandas は、スキーマを指定してそれに固執することを強制しません。これにより、開始時の速度が向上しますが、将来のバグや混乱のために多額の費用がかかることがよくあります.


これは、一般的な落とし穴に注意を払っていない初心者にとって特に問題です。たとえば、Pandas を扱っていたとき、datetime 列が文字列で構成されている (したがって、 objectとして分類されている) ことに気付くためにだけ、datetime 操作を試みることがよくありました。私は単純にこれを行います:


 df['Date'] = df['Date'].astype('datetime64[ns]')


Pandas の日付パーサーが私の文字列を読み違えていて、日付が意味をなさないことを後で知りました。

ファイルと CSV

http://www.reddit.com/r/Panda_Gifs/comments/32x49o/keep_rollin_rollin_rollin_rollin/


正直に言うと、ほとんどの人はデータフレームを CSV として保存しています。パンダの学生は、これを行うことを歓迎します。これは悪い考えです!


確かに、CSV は人間が読める形式であり、その利点はここまでです。それらの欠点は次のとおりです。


  • CSV に変換すると、スキーマと列の型に関するすべての情報が失われます。すべてがテキストに戻ります。


  • CSV は、不適切なフォーマット、破損、および解析エラーが発生しやすい傾向があります。


  • CSV は圧縮が難しいため、ストレージ コストが増加します。


  • CSV 形式は指定されていません。つまり、さまざまなプログラムがさまざまな方法で CSV を作成し、それらを解析する方法を理解するのはユーザーの負担になります。データの専門家なら誰でも証明するように、これはすぐに地獄のような体験に変わる可能性があります。


スキーマの損失は、通常、pandas で作業する人々にとって最大の問題です。これは一般的な状況です。


  1. あなたの仕事はCSVから始まります。適切なフォーマット、エンコーディング、quote char 仕様、および pandas のread_csvへの残りの多くの引数を理解していれば、それをデータフレームにロードします。ここで、時間をかけて列を調査し、各列を正しい型にキャストし、プロセスで発生するバグに対処し、最終結果が理にかなっていることを確認する必要があります。 (または、すぐに作業を開始して、後で多くのバグに直面することもできます)。


  2. 作業が完了すると、新しいデータフレームが作成されます。あなたはそれで何をするつもりですか?なぜ、CSVとして保存します。データフレームがテキストにダンプされるため、スキーマ定義に関する以前の作業はすべてなくなりました。


  3. 別のワークフロー用に新しいデータフレームをロードする必要があります。これは、ダンプしたばかりの CSV をロードすることを意味します。スキーマを正常に復元できる関数を作成したことを願っています。そうしないと、作業を最初からやり直す必要があります (各列が何をすべきかを覚えている場合)。


  4. CSV を友人と共有したり、GitHub に投稿したりしたいですか?スキーマを再代入できるコードを共有したほうがよいでしょう。彼らが喜んでそれを実行できることを願っています。または、テキストの塊が残り、すべてのスキーマ代入作業を最初からやり直す必要があります。


ばかげているように聞こえますか?私はこれが数え切れないほど行われるのを見てきました。私はこれを自分でやった!しかし今思うのは、なぜ私たちは人々にこのような働き方を教えているのだろうかということです。そのような狂気と残酷さを正当化するものは何ですか?


ここには 2 つの解決策があります。


本当に pandas で作業する必要がある場合は、データフレームを Parquet にエクスポートしてください。

または、SQL で作業して、すべての問題を解決することもできます。結局のところ、データベースはデータを保存するのに最適な場所です。


自問してみてください:なぜファイル層が必要なのですか?データを読み取って処理し、結果を保存するだけの場合は、おそらくそうではありません。データベースから読み込み、データベースで作業し、データベースに保存します。それはとても簡単です。外部とデータを共有する必要がありますか?寄木細工でエクスポートします。


世界はこれ以上 CSV を必要としません。

注: データフレームをピクルしてスキーマの問題を解決しようとする人もいます。これはひどい考えです。


ピクルス化は非効率的で安全ではありません (信頼できないピクルスを開かないでください!)。 pickle 化されたデータフレームは Python 内でのみ開くことができ、同じライブラリ環境内で発生する必要があります (ユーザーはまったく何も知らない可能性があります)。 pickle を読み取るパンダが、それを書き込んだパンダとは異なるバージョンである場合、ファイルを読み取れない可能性があります。


CSV ファイルを共有する pandas ユーザー


ヌル

SQL は NULL 値を使用して欠落データを示します。 null は簡単に除外できます。


 SELECT * FROM salaries WHERE equity_comp IS NOT NULL AND cash_comp IS NOT NULL


Pandas では、欠損値は次のいずれかになります。


  • Python のネイティブNone (Pandas ではNoneとして表示されますが、 nanのように扱われます)

  • numpy.nan

  • pandas.NA

  • pandas.NaT (日時用)


最も一般的なnumpy.nanに注目しましょう。


  • このオブジェクトの型はfloatであるため、型チェックで検出することは忘れてください。

  • それは真実なので、ブール値のテストを忘れてください。 bool(np.nan)Trueです。

  • numpy.nan == numpy.nanが false であるため、同等性テストに失敗します。 nanはそれ自体と等しくありません!

  • 操作でnanを使用しても例外はスローされません。結果がnanであることを意味するだけです。


楽しくないですか?



nanを検出する唯一の方法は、 pandas.isna()を使用することです。ドキュメントを読んで、pythonic の本能をすべて忘れたら、それで問題ありません。それでも、この動作は初心者にとって非常に紛らわしいものです。


Pandas で上記のクエリを複製する方法は次のとおりです。


 new_df = df.dropna(subset=["equity_comp", "cash_comp"])

制約

制約は SQL で重要です。これにより、データの安全性と一貫性を維持するルールを指定できます。たとえば、各行の一意の識別子として機能する主キーは、null ではなく一意である必要があります。


パンダにはこのようなものはありません。


pandas の主キーに最も近いのはインデックスです。残念ながら、インデックス値は繰り返しと null の両方になる可能性があります (はい、 None値を持つインデックスを持つことができます)。


ユーザーは、多くの場合、インデックスが主キーであるという暗黙の仮定を使用して作業します。これは、デフォルトのインデックスが[0,1,2,3,4...]の整数で構成されているという事実によって強制される考え方です。したがって、人々はインデックスを使用して特定の行を参照する傾向があります (例: df.loc[2]


これは愚かな信仰の行為です。これは、異なるデータフレームを連結またはマージするときに明らかになります。同様のインデックスが混同され、 [0,1,2,2,2,3...]のようなインデックスが得られることがよくあります。


Pandas はこれに関する警告をスローしないため、最初は気付かないでしょう。しかし、次にdf.loc[2]を使用すると、単一の行ではなく 3 つの行を持つデータフレームが返されるため、コードが壊れます。


各行が再び一意の値を取得するように、マージされたデータフレームでreset_index()を実行する必要があることを理解する前に、多くの涙が流れます。


さらに、SQL 制約により、書き込み時にチェックを実行できます。 NOT NULL制約を持つ列に NULL 値を挿入しようとすると、例外が発生し、不正な書き込みは発生しません。 Pandas では、読み取り時にのみチェックを実行できます。つまり、あなたがそれをすることを覚えていれば。

ベクトル化された操作

これは主に教育上のポイントです。よく知られているように、Pandas は、ベクトル化された操作 (シリーズのすべての要素が並列にアクセスされる) を許可し、さらには推奨しています。


しかし、Python で作業している多くの人は、自動的にこのように考えるわけではありません。彼らはループを学ぶことから始めましたが、今では Guido によって、それらのループを使用したいと考えています。


iterrowsを使い始めると、すぐに iterrows メソッドとitertuplesメソッドを発見し、データフレームを行ごとにループできるようにします。


ベクトルで考えるように強制するものは何もないため、ほとんど必然的に、彼らは再びループパターンに陥ります。これにより、実行速度が非常に遅いひどいコードを作成することになります。


pandas での長い経験の後、私は SQL に注目し始めました。 SQL の問題に直面するたびに、私の本能はループ ソリューションを思いつくことでした。残念なことに、SQL ではそれができませんでした。


その宣言構文により、列操作、JOIN、およびウィンドウ関数の観点から考える必要がありました。徐々に、より優れたアナリストになる新しい一連のメンタル モデルを構築しました。


学習者は、pandas を始める前に、SQL でデータを操作する自信をつけるべきだと思います。行ごとのループが避けられない場合 (これはまれです) をよりよく理解できるようになります。

不変性

データフレームをメモリにロードします。そのデータフレームを変更する必要があります。その場で変更しますか、それともコピーを作成しますか?既存の列を更新するか、新しい列を作成する必要がありますか?


複数のデータフレーム スライスを作成する必要がある場合は、各スライスで何らかの作業を行いますか?各スライスを個別の変数に格納するか、同じ変数を使用して異なるスライスを順番に保持する必要がありますか?


人々が pandas で作業するとき、これらすべてのことを同時に行う傾向があります。データフレーム、データフレームのスライス、およびスライスのスライスを含むすべての変数を追跡し、データがどのように追加または変更されたかを知ることはすぐに困難になります。


(いつも pandas と書いているわけではありませんが、書くと copy warning の設定が入ります。)


ほとんどの人は pandas をノートブックで使用しているため、これらの問題は典型的なノートブックの落とし穴と組み合わさり、最終的に大きな頭痛の種になります。

これが、pandas がデータ分析に最適な選択肢ではないと私が考える理由の 1 つです。


SQL でデータを処理する場合、元のデータは変更しません。 UPDATEステートメントは分析では使用されません。代わりに、さまざまな選択を表すテーブルとビューのパイプラインを作成します。


結果を保存する必要がある場合は、新しいテーブルを作成します (または、既存のターゲット テーブルに行を追加しますが、以前の行を変更または削除することはありません)。これは、不変性の信条を尊重します。つまり、ソース データを変更したり削除したりしないでください。これにより、プロセスが安全で透過的になり、複製が容易になります。


はい、pandas で不変性を尊重することはできますが、そうするべきかどうかは明らかではなく、多くの人はそれを学ぶことはありません。一般的に見られるのは、ファイルのレベルでの不変性です。通常、人々は CSV をロードして、新しい CSV を出力します。しかし、その間に起こる仕事のために?何でもあり。


(ほとんどのinplaceメソッドは、前のデータフレームを変更するのではなく、新しいデータフレームを返すため、理論的には「純粋」です。しかし、それらはすべて、データフレームをその場で変更するインプレース オプションを提供します。そして、人々はそれを喜んで使用します。)

パンダが足りないとき

pandas で本格的な作業を行うと、最終的にはパフォーマンスの壁にぶつかります。分析しているデータが大きすぎるか、処理のニーズが高すぎます。


これは、パンダの研究をしていたときによく見かけました。それが起こったとき、私の同僚と私は「パンダをより速くする」とグーグルで検索し、このホットな話題に関する数え切れないほどの記事を見つけました。


このような状況にある場合は、利用可能なリソースをぜひチェックしてください。特にpandas のより良い使い方を説明するもの。しかし、期待を高くしすぎないでください。パンダができることには厳しい制限があります。大丈夫です。データ分析のすべてを終わらせるように設計されたわけではありません。


データ ワークロードをスケーリングする必要がある場合の最適な代替手段は次の 2 つです。


  • パイスパーク。 Spark は、大規模な分析と並列化されたデータ処理のためのエンジンです。 PySpark を使用すると、Python でそれを活用でき、pandas を連想させる構文を使用します。 pandas API もあります。


  • データ ウェアハウス。非常に大規模 (テラバイトやペタバイトと考えてください) でデータを保存および分析するためのシステム。最新のデータ ウェアハウスはクラウドで実行されるため、サーバーを管理することなく分散システムの機能を活用できます。 Google Cloud のデータ ウェアハウス ソリューションである BigQuery は、30 秒で 1,000 億行または 7 テラバイトのデータを処理できます。通常、データ ウェアハウスは SQL で動作します。 (BigQuery を無料で試してみたい方 は、こちらに書きました。

パンダはいつより良いですか?

パンダを遠ざけてほしくありません。これは間違いなく学ぶ価値のある素晴らしいツールです。


pandas が SQL よりも適している場合があります。ここでは詳しく説明しませんが、簡単なリストを次に示します。


  • 他の Python ワークフローと統合する場合 (機械学習を行っている場合や、Python 視覚化ライブラリを使用したい場合など)。


  • 簡単な統計が必要な場合。 describe()メソッドは非常に便利です。


  • 規模や再現性を気にせずに、すばやく分析を行う必要がある場合。ただし、Excel や Google スプレッドシートも同様に機能する場合があります。


  • Python アプリケーションを構築している場合。 Pandas は、任意のデータ構造からテーブルに、またはその逆に移動する最も速い方法かもしれません。


  • 実際に命令型のワークフローとループが必要な場合。たとえば、マルコフ シミュレーションの構築。


  • 通常とは異なる関数を作成または再利用する必要がある場合。 Pandas は、任意の Python 関数を適用するのに優れています。


  • 非常に動的でパラメーター化されたワークフローがある場合。

結論

パンダをあきらめるように頼まないでください


この記事が、SQL と pandas、およびそれらの相対的な長所と短所についてより深く考えるきっかけになれば幸いです。


現在のデータの傾向はパンダに有利に傾いていると思います。SQL は自己責任で無視してください。


これが私のアドバイスです:


  • 学習者の場合: SQL を学習し、それを分析に使用する方法を学びます。後悔することはありません。


  • あなたがカリキュラムの設計者である場合: 生徒がテーブルで夢を見て、すべて大文字で話すまで、生徒を SQL で溺れさせます。それはタフな愛であり、彼らはあなたを憎むでしょうが、いつの日か彼らは理解するでしょう. (ただし、頭を殴らないでください。)


  • あなたが指導者の場合: 生徒を Pandas から徐々に引き離し、SQL の問題に挑戦するように促してください。


会話を盛り上げたいです。コメントを残すか、私にメールを書くか、 LinkedInに私を追加してください。