ホームページ > バックエンド開発 > Python チュートリアル > Python メモリ最適化をマスターする: データ サイエンスと機械学習のテクニック

Python メモリ最適化をマスターする: データ サイエンスと機械学習のテクニック

Barbara Streisand
リリース: 2025-01-20 06:14:10
オリジナル
386 人が閲覧しました

Mastering Python Memory Optimization: Techniques for Data Science and Machine Learning

多作な作家として、私の Amazon の書籍コレクションをぜひご覧ください。 忘れずに Medium で私をフォローして最新情報を入手し、サポートを示してください。ご激励をよろしくお願いいたします!

データ サイエンスと機械学習における Python の重要性が高まっているため、大規模プロジェクトでは効率的なメモリ管理が必要です。 データセットのサイズが拡大し、計算需要が増大しているため、メモリ使用量の最適化が重要になっています。 メモリ集約型の Python アプリケーションに関する私の経験から、いくつかの効果的な最適化戦略が生まれました。それをここで共有します。

数値計算の基礎となるライブラリである NumPy から始めます。 NumPy 配列は、特に大規模なデータセットの場合、Python リストに比べてメモリ上の大幅な利点を提供します。 連続したメモリ割り当てと静的型付けにより、オーバーヘッドが最小限に抑えられます。

次の比較を考えてみましょう:

<code class="language-python">import numpy as np
import sys

# Creating a list and a NumPy array with 1 million integers
py_list = list(range(1000000))
np_array = np.arange(1000000)

# Comparing memory usage
print(f"Python list size: {sys.getsizeof(py_list) / 1e6:.2f} MB")
print(f"NumPy array size: {np_array.nbytes / 1e6:.2f} MB")</code>
ログイン後にコピー
ログイン後にコピー

NumPy 配列のメモリ使用量が小さいことは明らかです。 この差異は、データセットが大きくなるほど顕著になります。

NumPy はメモリ効率の高い操作も提供します。 操作ごとに新しい配列を生成する代わりに、多くの場合、配列をインプレースで変更します。

<code class="language-python"># In-place operations
np_array += 1  # Modifies the original array directly</code>
ログイン後にコピー
ログイン後にコピー

Pandas に目を向けると、カテゴリカル データ型がメモリ最適化の鍵となります。 一意の値が制限されている文字列列の場合、カテゴリ型に変換するとメモリ消費量が大幅に削減されます。

<code class="language-python">import pandas as pd

# DataFrame with repeated string values
df = pd.DataFrame({'category': ['A', 'B', 'C'] * 1000000})

# Memory usage check
print(f"Original memory usage: {df.memory_usage(deep=True).sum() / 1e6:.2f} MB")

# Conversion to categorical
df['category'] = pd.Categorical(df['category'])

# Post-conversion memory usage
print(f"Memory usage after conversion: {df.memory_usage(deep=True).sum() / 1e6:.2f} MB")</code>
ログイン後にコピー
ログイン後にコピー

特に繰り返しの文字列を含む大規模なデータセットの場合、メモリを大幅に節約できます。

スパース データセットの場合、Pandas はスパース データ構造を提供し、null 以外の値のみを保存するため、多数の null またはゼロ値を持つデータセットのメモリを大幅に節約できます。

<code class="language-python"># Creating a sparse series
sparse_series = pd.Series([0, 0, 1, 0, 2, 0, 0, 3], dtype="Sparse[int]")

print(f"Memory usage: {sparse_series.memory_usage(deep=True) / 1e3:.2f} KB")</code>
ログイン後にコピー
ログイン後にコピー

データセットが利用可能な RAM を超えると、メモリ マップされたファイルは変化します。 ファイル全体をロードせずに、メモリ内にあるかのように大きなファイルを操作できるようになります。

<code class="language-python">import mmap
import os

# Creating a large file
with open('large_file.bin', 'wb') as f:
    f.write(b'0' * 1000000000)  # 1 GB file

# Memory-mapping the file
with open('large_file.bin', 'r+b') as f:
    mmapped_file = mmap.mmap(f.fileno(), 0)

# Reading from the memory-mapped file
print(mmapped_file[1000000:1000010])

# Cleaning up
mmapped_file.close()
os.remove('large_file.bin')</code>
ログイン後にコピー
ログイン後にコピー

これは、大きなファイルをメモリに完全にロードせずにランダムにアクセスする場合に特に便利です。

ジェネレーター式と itertools は、メモリ効率の高いデータ処理に強力です。すべてを同時にメモリにロードすることなく、大規模なデータセットを処理できます:

<code class="language-python">import itertools

# Generator expression
sum_squares = sum(x*x for x in range(1000000))

# Using itertools for memory-efficient operations
evens = itertools.islice(itertools.count(0, 2), 1000000)
sum_evens = sum(evens)

print(f"Sum of squares: {sum_squares}")
print(f"Sum of even numbers: {sum_evens}")</code>
ログイン後にコピー
ログイン後にコピー

これらの手法により、大規模なデータセットを処理する際のメモリ オーバーヘッドが最小限に抑えられます。

パフォーマンスが重要なコード セクションに対して、Cython は大幅な最適化の可能性を提供します。 Python コードを C にコンパイルすると、速度が大幅に向上し、メモリが削減される可能性があります:

<code class="language-cython">def sum_squares_cython(int n):
    cdef int i
    cdef long long result = 0
    for i in range(n):
        result += i * i
    return result

# Usage
result = sum_squares_cython(1000000)
print(f"Sum of squares: {result}")</code>
ログイン後にコピー

この Cython 関数は、特に n 値が大きい場合、純粋な Python 関数よりも優れたパフォーマンスを発揮します。

ジャストインタイム コンパイラである PyPy は、自動メモリ最適化を提供します。 これは、長時間実行されるプログラムに特に有益であり、多くの場合、メモリ使用量が大幅に削減されます:

<code class="language-python">import numpy as np
import sys

# Creating a list and a NumPy array with 1 million integers
py_list = list(range(1000000))
np_array = np.arange(1000000)

# Comparing memory usage
print(f"Python list size: {sys.getsizeof(py_list) / 1e6:.2f} MB")
print(f"NumPy array size: {np_array.nbytes / 1e6:.2f} MB")</code>
ログイン後にコピー
ログイン後にコピー

PyPy は、標準の CPython と比較してメモリ効率と速度の向上につながります。

メモリ プロファイリングは、最適化の機会を特定するために不可欠です。 memory_profiler ライブラリは貴重なツールです:

<code class="language-python"># In-place operations
np_array += 1  # Modifies the original array directly</code>
ログイン後にコピー
ログイン後にコピー

メモリ使用量を視覚化するには、mprof run script.pymprof plot を使用します。

メモリ リークに対処することは非常に重要です。 tracemalloc モジュール (Python 3.4 ) は、メモリ割り当てソースの識別に役立ちます:

<code class="language-python">import pandas as pd

# DataFrame with repeated string values
df = pd.DataFrame({'category': ['A', 'B', 'C'] * 1000000})

# Memory usage check
print(f"Original memory usage: {df.memory_usage(deep=True).sum() / 1e6:.2f} MB")

# Conversion to categorical
df['category'] = pd.Categorical(df['category'])

# Post-conversion memory usage
print(f"Memory usage after conversion: {df.memory_usage(deep=True).sum() / 1e6:.2f} MB")</code>
ログイン後にコピー
ログイン後にコピー

これにより、メモリを大量に使用するコード セクションが特定されます。

非常にメモリを大量に消費するアプリケーションの場合、カスタム メモリ管理が必要になる場合があります。 これには、オブジェクトの再利用またはカスタム キャッシュのためのオブジェクト プールが関係する可能性があります:

<code class="language-python"># Creating a sparse series
sparse_series = pd.Series([0, 0, 1, 0, 2, 0, 0, 3], dtype="Sparse[int]")

print(f"Memory usage: {sparse_series.memory_usage(deep=True) / 1e3:.2f} KB")</code>
ログイン後にコピー
ログイン後にコピー

これにより、オブジェクトの作成/破棄のオーバーヘッドが最小限に抑えられます。

非常に大規模なデータセットの場合は、Dask のようなアウトオブコア計算ライブラリを検討してください。

<code class="language-python">import mmap
import os

# Creating a large file
with open('large_file.bin', 'wb') as f:
    f.write(b'0' * 1000000000)  # 1 GB file

# Memory-mapping the file
with open('large_file.bin', 'r+b') as f:
    mmapped_file = mmap.mmap(f.fileno(), 0)

# Reading from the memory-mapped file
print(mmapped_file[1000000:1000010])

# Cleaning up
mmapped_file.close()
os.remove('large_file.bin')</code>
ログイン後にコピー
ログイン後にコピー

Dask は、計算を小さなチャンクに分割することで、利用可能な RAM よりも大きなデータセットを処理します。

アルゴリズムの最適化も重要です。 効率的なアルゴリズムを選択すると、メモリ使用量を大幅に削減できます:

<code class="language-python">import itertools

# Generator expression
sum_squares = sum(x*x for x in range(1000000))

# Using itertools for memory-efficient operations
evens = itertools.islice(itertools.count(0, 2), 1000000)
sum_evens = sum(evens)

print(f"Sum of squares: {sum_squares}")
print(f"Sum of even numbers: {sum_evens}")</code>
ログイン後にコピー
ログイン後にコピー

この最適化されたフィボナッチ関数は、単純な再帰実装とは異なり、定数メモリを使用します。

要約すると、効果的な Python メモリ最適化は、効率的なデータ構造、特殊なライブラリ、メモリ効率の高いコーディング、および適切なアルゴリズムを組み合わせたものです。 これらの手法によりメモリ フットプリントが削減され、より大きなデータセットやより複雑な計算の処理が可能になります。 コードのプロファイリングを忘れずに行ってボトルネックを特定し、最も大きな影響を与える最適化の取り組みに焦点を当ててください。


101 冊

著者

Aarav Joshi が共同設立した AI を活用した出版社 101 Books は、AI を活用して出版コストを最小限に抑え、質の高い知識にアクセスできるようにしています (一部の書籍は、 4 ドル!).

Amazon で Golang Clean Code の本を見つけてください。

アップデートやその他のタイトルについては、Amazon で Aarav Joshi を検索してください。 特別割引は [リンク] からご利用いただけます。

私たちの作品

私たちの作品をご覧ください:

インベスターセントラル | 投資家中央スペイン人 | 中央ドイツの投資家 | スマートな暮らし | エポックとエコー | 不可解な謎 | ヒンドゥーヴァ | エリート開発者 | JS スクール


私たちは中程度です

Tech Koala Insights | エポックズ&エコーズワールド | インベスター・セントラル・メディア | 不可解な謎 中 | 科学とエポックミディアム | 現代ヒンドゥーヴァ

以上がPython メモリ最適化をマスターする: データ サイエンスと機械学習のテクニックの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート