89520


KaggleのNotebook上で以下のようなpandas.DataFrameをnumpy.ndarrayに変換したいです。

[code]

    >>> train.info()
    <class 'pandas.core.frame.DataFrame'>
    Index: 458913 entries, 0000099d6bd597052cdcda90ffabf56573fe9d7c79be5fbac11a8ed792feb62a to fffff1d38b785cef84adeace64f8f83db3a0c31e8d92eaba8b115f71cab04681
    Columns: 918 entries, P_2_mean to D_68_<lambda_0>
    dtypes: float64(891), int64(25), object(2)
    memory usage: 3.1+ GB
    
[/code]

上記コマンド実行時のKaggleのNotebookのRAMは最大16GBのうち6.6GB使用されています。

この状態で以下のコードを実行すると、KaggleのNotebookに`Your notebook tried to allocate more memory
than is available. It has restarted.`とエラーが発生します。

[code]

    >>> train_narray = train.to_numpy(copy=False)
    
[/code]

[APIリファレンス](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_numpy.html)から`copy=False`を指定した場合もコピーが作成される場合もあるということは分かったのですが、RAM使用量が2.4倍以上に膨れ上がるのは納得いきません。

> Note that copy=False does not ensure that to_numpy() is no-copy.

少ないRAMでpandas.DataFrameをnampy.ndarrayに変換する方法ありましたら教えていただけないでしょうか？


CC BY-SA 4.0
2022-06-21T12:43:07.390
89506
2022-06-22T02:59:07.010
27493
question
python pandas numpy kaggle
pandas.DataFrame.to_numpy()をすると使用メモリが増大する問題への対処


`DataFrame.to_numpy()`を実行したときにコピーが作成されないのは、元のデータフレームの全ての列が同じNumPyデータ型になっている場合だけです。

元のデータフレームは列によってデータ型が異なっています（`float64(891), int64(25),
object(2)`）。この場合は、データフレームの各列がそれぞれ別のNumPy配列になっています。  
ここで`DataFrame.to_numpy()`を実行すると、全ての列が1つのNumPy配列に統合されるるため、必ずデータ型を変換したコピーが作成されます（しかも質問の状況では、おそらく`train_narray`は高価なオブジェクトデータ型になります）。

解決策としては、列ごとに`Series.to_numpy()`を実行することです。  
あるいはデータ型が同じものに限って実行すれば（例えば`train.select_dtypes("int").to_numpy()`のように）、コピーが作成されたとしてもオブジェクトデータ型にキャストされることはないでしょう。

また`.to_records()`メソッドで、NumPyのレコード配列という列ごとに異なるデータ型を持てる配列に変換できます（コピーが作られます）が、私はあまり使ったことがないので、メモリにどのような影響があるのかはわかりません。


CC BY-SA 4.0
2022-06-22T02:59:07.010
89520
2022-06-22T02:59:07.010
37167
89506
answer