pandasデータフレームをNumPy配列に変換する 質問する

pandasデータフレームをNumPy配列に変換する 質問する

pandas データフレームを NumPy 配列に変換するにはどうすればよいですか?

データフレーム:

import numpy as np
import pandas as pd

index = [1, 2, 3, 4, 5, 6, 7]
a = [np.nan, np.nan, np.nan, 0.1, 0.1, 0.1, 0.1]
b = [0.2, np.nan, 0.2, 0.2, 0.2, np.nan, np.nan]
c = [np.nan, 0.5, 0.5, np.nan, 0.5, 0.5, np.nan]
df = pd.DataFrame({'A': a, 'B': b, 'C': c}, index=index)
df = df.rename_axis('ID')

与える

      A    B    C
ID                                 
1   NaN  0.2  NaN
2   NaN  NaN  0.5
3   NaN  0.2  0.5
4   0.1  0.2  NaN
5   0.1  0.2  0.5
6   0.1  NaN  0.5
7   0.1  NaN  NaN

これを次のように NumPy 配列に変換したいと思います。

array([[ nan,  0.2,  nan],
       [ nan,  nan,  0.5],
       [ nan,  0.2,  0.5],
       [ 0.1,  0.2,  nan],
       [ 0.1,  0.2,  0.5],
       [ 0.1,  nan,  0.5],
       [ 0.1,  nan,  nan]])

また、このように dtype を保存することは可能ですか?

array([[ 1, nan,  0.2,  nan],
       [ 2, nan,  nan,  0.5],
       [ 3, nan,  0.2,  0.5],
       [ 4, 0.1,  0.2,  nan],
       [ 5, 0.1,  0.2,  0.5],
       [ 6, 0.1,  nan,  0.5],
       [ 7, 0.1,  nan,  nan]],
     dtype=[('ID', '<i4'), ('A', '<f8'), ('B', '<f8'), ('B', '<f8')])

ベストアンサー1

使用df.to_numpy()

よりも優れているdf.values理由は次のとおりです。*

valuesおよびの使用を廃止する時期が来ましたas_matrix()

pandas v0.24.0 では、pandas オブジェクトから NumPy 配列を取得するための 2 つの新しいメソッドが導入されました。

  1. to_numpy()Indexは、、、SeriesおよびDataFrameオブジェクト上で定義され、
  2. arrayは、IndexおよびSeriesオブジェクトでのみ定義されます。

v0.24のドキュメントにアクセスすると.values次のような大きな赤い警告が表示されます:

警告:DataFrame.to_numpy()代わりに を使用することをお勧めします。

見るv0.24.0リリースノートのこのセクション、 そしてこの答え詳細については。

* - はto_numpy()、将来にわたって多くのバージョンで確実に実行する必要がある製品コードに推奨される方法です。ただし、jupyter またはターミナルでスクラッチパッドを作成するだけの場合は、.values入力時間を数ミリ秒節約するために を使用することは許容される例外です。いつでも、後から fit n finish を追加できます。



一貫性の向上に向けて:to_numpy()

API 全体の一貫性を高めるために、to_numpyDataFrames から基礎となる NumPy 配列を抽出する新しいメソッドが導入されました。

# Setup
df = pd.DataFrame(data={'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}, 
                  index=['a', 'b', 'c'])

# Convert the entire DataFrame
df.to_numpy()
# array([[1, 4, 7],
#        [2, 5, 8],
#        [3, 6, 9]])

# Convert specific columns
df[['A', 'C']].to_numpy()
# array([[1, 7],
#        [2, 8],
#        [3, 9]])

上で述べたように、このメソッドはオブジェクトIndexおよびSeriesオブジェクトでも定義されています(ここ)。

df.index.to_numpy()
# array(['a', 'b', 'c'], dtype=object)

df['A'].to_numpy()
#  array([1, 2, 3])

デフォルトではビューが返されるため、変更を加えると元のビューに影響します。

v = df.to_numpy()
v[0, 0] = -1
 
df
   A  B  C
a -1  4  7
b  2  5  8
c  3  6  9

代わりにコピーが必要な場合は、 を使用してくださいto_numpy(copy=True)


ExtensionTypes の pandas >= 1.0 アップデート

pandas 1.x を使用している場合は、拡張タイプをより多く扱うことになるでしょう。これらの拡張タイプが正しく変換されるように、もう少し注意する必要があります。

a = pd.array([1, 2, None], dtype="Int64")                                  
a                                                                          

<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64 

# Wrong
a.to_numpy()                                                               
# array([1, 2, <NA>], dtype=object)  # yuck, objects

# Correct
a.to_numpy(dtype='float', na_value=np.nan)                                 
# array([ 1.,  2., nan])

# Also correct
a.to_numpy(dtype='int', na_value=-1)
# array([ 1,  2, -1])

これはドキュメントで言及されている


dtypes結果にが必要な場合...

別の回答に示されているように、DataFrame.to_recordsこれはこれを行う良い方法です。

df.to_records()
# rec.array([('a', 1, 4, 7), ('b', 2, 5, 8), ('c', 3, 6, 9)],
#           dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8'), ('C', '<i8')])

残念ながら、これは では実行できませんto_numpy。ただし、代わりに を使用できますnp.rec.fromrecords

v = df.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
# rec.array([('a', 1, 4, 7), ('b', 2, 5, 8), ('c', 3, 6, 9)],
#           dtype=[('index', '<U1'), ('A', '<i8'), ('B', '<i8'), ('C', '<i8')])

パフォーマンス的には、ほぼ同じです (実際、 を使用するとrec.fromrecords少し速くなります)。

df2 = pd.concat([df] * 10000)

%timeit df2.to_records()
%%timeit
v = df2.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())

12.9 ms ± 511 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.56 ms ± 291 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


新しいメソッドを追加する理由

to_numpy()(に加えてarray)は、2つのGitHubの問題での議論の結果として追加されました。GH19954そしてGH23623

具体的には、ドキュメント根拠を述べます:

[ ...] の場合、.values返される値が実際の配列なのか、その変換なのか、あるいは pandas のカスタム配列 ( など) の 1 つなのかは不明でしたCategorical。たとえば、 の場合PeriodIndex、は毎回、期間オブジェクトの.values新しい を生成します。 [...]ndarray

to_numpyAPI の一貫性を向上させることを目指しており、これは正しい方向への大きな一歩です。.values現在のバージョンでは廃止されませんが、将来的には廃止される可能性があると予想されるため、ユーザーにはできるだけ早く新しい API に移行することを強くお勧めします。



他の解決策に対する批判

DataFrame.valuesすでに述べたように、動作に一貫性がありません。

DataFrame.get_values()だったv1.0でひっそりと削除されましたは v0.25 で非推奨になりました。それ以前は、 の単なるラッパーだったのでDataFrame.values、上記の内容がすべて適用されます。

DataFrame.as_matrix()v1.0 で削除され、v0.23 では非推奨になりました。使用しないでください

おすすめ記事