パンダデータフレームをNumPy配列に変換


465

パンダのデータフレームを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')

与える

label   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')])

または類似?


5
なぜこれが必要なのですか?とにかくnumpy配列に基づいたデータフレームではありませんか?numpy配列が必要な場合は、データフレームを使用できるはずです。これが、関数がnumpy配列を要求するscikit-learnでデータフレームを使用できる理由です。
chrisfs

(1):ここでは、おそらく関連dtypes&recarrays(別名レコードの配列や構造配列)についてのリンクのカップルですstackoverflow.com/questions/9949427/... (2) stackoverflow.com/questions/52579601/...
ヨーネ

注: Pandas DataFrameをこのような配列(またはリスト)に変換する必要がある場合は、他の問題を示している可能性があります。私は強くDATAFRAMEがあなたの特定のユースケースに適したデータ構造であることを確実にすることをお勧めします、とパンダはあなたに興味を持っている操作を実行する任意の方法が含まれていないこと。
AMC

回答:


391

パンダデータフレーム(df)をnumpy ndarrayに変換するには、次のコードを使用します。

df.values

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]])

239

valuesおよびの使用を廃止してくださいas_matrix()

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

  1. to_numpy()、およびオブジェクトで定義されIndexSeries,DataFrame
  2. arrayIndexSeriesオブジェクトでのみ定義されます。

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

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

詳細については、v0.24.0リリースノートのこのセクションこの回答をご覧ください。


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

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

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

df.to_numpy()
array([[1, 4],
       [2, 5],
       [3, 6]])

上述したように、このメソッドは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
a -1  4
b  2  5
c  3  6

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

ExtensionTypesのパンダ> = 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

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

これはドキュメントで呼び出されます。

あなたが必要な場合dtypes...

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

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

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

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

11.1 ms ± 557 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.67 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

新しいメソッドを追加する根拠

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

具体的には、ドキュメントは根拠に言及しています:

[...] .values戻り値が実際の配列、それの何らかの変換、またはpandasカスタム配列(などCategorical)のいずれであるかは明確ではありませんでした。たとえば、を 使用するとPeriodIndex、毎回.values新しいndarray期間オブジェクトが生成されます。[...]

to_numpyAPIの一貫性を改善することを目指しています。これは正しい方向への主要なステップです。.values現在のバージョンでは廃止されませんが、これは将来のいずれかの時点で発生する可能性があるため、できるだけ早く新しいAPIに移行することをユーザーにお願いします。


他のソリューションの批評

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

DataFrame.get_values()は単なるラッパーなDataFrame.valuesので、上記のすべてが適用されます。

DataFrame.as_matrix()は現在非推奨です。使用しないでください!


列の選択機能を回復する方法を説明せずにas_matrix、この場合、肺の上部で叫んで別の解決策に切り替える人々のページを次々に読むことがどのように可能かわかりません!列を選択する方法は他にもあると思いますが、そのうちの1つでした!to_numpyas_matrixas_matrix
ジェレミー

@Jérémieは明らかdf[[col1, col2']].to_numpy()ですか?廃止された関数の更新された代替案を宣伝したいと思う理由がわからないので、答えに反対票を投じる必要があります。
cs95

列の一部がリストタイプの場合。これから平らなでこぼこの配列を作成するにはどうすればよいですか?
モニバ

@Monibaあなたは最初にあなたの要件に従ってリストアイテムを別々の列/行に分解したいと思うかもしれません。
cs95

私が間違っていない限り、同じ呼び出しで複数の列を取得すると、すべてのデータが1つの大きな配列にマージされます。何か不足していますか?
Andrea Moro

128

.as_matrix()この回答で使用されているメソッドは廃止されています。パンダ0.23.4は警告します:

メソッド.as_matrixは将来のバージョンで削除される予定です。代わりに.valuesを使用してください。


パンダには何かが組み込まれています...

numpy_matrix = df.as_matrix()

与える

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]])

30
これは構造化配列を提供せず、すべての列はdtype objectです。
sebix 2014年

14
「バージョン0.23.0以降非推奨:代わりにDataFrame.valuesを使用してください。」/「このメソッドは下位互換性のために提供されています。通常、「。values」を使用することをお勧めします。」- github.com/pandas-dev/pandas/blob/...
デヴィッド・J.

4
これは非推奨になりました。v0.24以降では、to_numpy代わりに(.valuesどちらでもない)を使用してください。詳細はこちら
cs95

1
「FutureWarning:メソッド.as_matrixは将来のバージョンで削除されます。代わりに.valuesを使用してください。」
Farhad Maleki

66

DataFrame.reset_index()関数とDataFrame.values関数をチェーンして、インデックスを含むデータフレームのNumpy表現を取得します。

In [8]: df
Out[8]: 
          A         B         C
0 -0.982726  0.150726  0.691625
1  0.617297 -0.471879  0.505547
2  0.417123 -1.356803 -1.013499
3 -0.166363 -0.957758  1.178659
4 -0.164103  0.074516 -0.674325
5 -0.340169 -0.293698  1.231791
6 -1.062825  0.556273  1.508058
7  0.959610  0.247539  0.091333

[8 rows x 3 columns]

In [9]: df.reset_index().values
Out[9]:
array([[ 0.        , -0.98272574,  0.150726  ,  0.69162512],
       [ 1.        ,  0.61729734, -0.47187926,  0.50554728],
       [ 2.        ,  0.4171228 , -1.35680324, -1.01349922],
       [ 3.        , -0.16636303, -0.95775849,  1.17865945],
       [ 4.        , -0.16410334,  0.0745164 , -0.67432474],
       [ 5.        , -0.34016865, -0.29369841,  1.23179064],
       [ 6.        , -1.06282542,  0.55627285,  1.50805754],
       [ 7.        ,  0.95961001,  0.24753911,  0.09133339]])

dtypeを取得するには、このndarrayをviewを使用して構造化配列に変換する必要があります

In [10]: df.reset_index().values.ravel().view(dtype=[('index', int), ('A', float), ('B', float), ('C', float)])
Out[10]:
array([( 0, -0.98272574,  0.150726  ,  0.69162512),
       ( 1,  0.61729734, -0.47187926,  0.50554728),
       ( 2,  0.4171228 , -1.35680324, -1.01349922),
       ( 3, -0.16636303, -0.95775849,  1.17865945),
       ( 4, -0.16410334,  0.0745164 , -0.67432474),
       ( 5, -0.34016865, -0.29369841,  1.23179064),
       ( 6, -1.06282542,  0.55627285,  1.50805754),
       ( 7,  0.95961001,  0.24753911,  0.09133339),
       dtype=[('index', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])

3
この回答で唯一欠けているのは、一般的な関数を記述できるようにデータフレームからdtypeを構築する方法です
Joseph Garvin

32

このto_records方法を使用できますが、dtypeが最初から必要なものでない場合は、dtypeを少し試してみる必要があります。私の場合、DFを文字列からコピーしたので、インデックスタイプは文字列です(objectパンダではdtypeで表されます)。

In [102]: df
Out[102]: 
label    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

In [103]: df.index.dtype
Out[103]: dtype('object')
In [104]: df.to_records()
Out[104]: 
rec.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=[('index', '|O8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
In [106]: df.to_records().dtype
Out[106]: dtype([('index', '|O8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])

recarray dtypeの変換は私にはうまくいきませんが、Pandasでこれを既に行うことができます:

In [109]: df.index = df.index.astype('i8')
In [111]: df.to_records().view([('ID', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
Out[111]:
rec.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', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])

PandasはID、エクスポートされたレコード配列(バグ?)でインデックスの名前を適切に(に)設定しないことに注意してください。そのため、型変換を利用してそれも修正します。

現時点では、Pandasには8バイトの整数、i8浮動小数点数しかありませんf8(この問題を参照)。


2
求められている構造化配列(recarrayよりも優れたパフォーマンス)を取得するには、recarrayをnp.arrayコンストラクターに渡すだけです。
隕石

上記のインデックスの名前を設定するための修正を加えました。
Chang She、

26

df.to_records()うまくいくようです。あなたが探している正確な機能が要求されたto_recordsの代替と指摘します。

私はあなたの例を使ってこれをローカルで試しました、そしてその呼び出しはあなたが探していた出力に非常に似たものをもたらします:

rec.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=[(u'ID', '<i8'), (u'A', '<f8'), (u'B', '<f8'), (u'C', '<f8')])

これはではrecarrayなくであることに注意してくださいarray。コンストラクタをとして呼び出すことにより、結果を通常のnumpy配列に移動できnp.array(df.to_records())ます。


3
to_records()5年以上前に言及された@meteoreによる他の回答と比較して、この回答は何を追加しますか?
JohnE 2018年

13

これを試して:

a = numpy.asarray(df)

こんにちは!回答に説明を追加してください。現時点では、長さコンテンツのため、レビューにより低品質としてマークされており、システムによって削除されるリスクがあります。ありがとう!
d_kennetz

1
基本的に、入力を配列に変換します(名前が示すとおり)。したがって、質問のコンテキストとともに、この回答は有効です。docs.scipy.org/doc/numpy/reference/generated/…を
Lautaro Parada Opazo

ありがとう、それは一種の自明だと思います。
Dadu Khan、

8

これが、pandas DataFrameから構造体配列を作成する私のアプローチです。

データフレームを作成する

import pandas as pd
import numpy as np
import six

NaN = float('nan')
ID = [1, 2, 3, 4, 5, 6, 7]
A = [NaN, NaN, NaN, 0.1, 0.1, 0.1, 0.1]
B = [0.2, NaN, 0.2, 0.2, 0.2, NaN, NaN]
C = [NaN, 0.5, 0.5, NaN, 0.5, 0.5, NaN]
columns = {'A':A, 'B':B, 'C':C}
df = pd.DataFrame(columns, index=ID)
df.index.name = 'ID'
print(df)

      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

pandas DataFrameからnumpy構造体配列(レコード配列ではない)を作成する関数を定義します。

def df_to_sarray(df):
    """
    Convert a pandas DataFrame object to a numpy structured array.
    This is functionally equivalent to but more efficient than
    np.array(df.to_array())

    :param df: the data frame to convert
    :return: a numpy structured array representation of df
    """

    v = df.values
    cols = df.columns

    if six.PY2:  # python 2 needs .encode() but 3 does not
        types = [(cols[i].encode(), df[k].dtype.type) for (i, k) in enumerate(cols)]
    else:
        types = [(cols[i], df[k].dtype.type) for (i, k) in enumerate(cols)]
    dtype = np.dtype(types)
    z = np.zeros(v.shape[0], dtype)
    for (i, k) in enumerate(z.dtype.names):
        z[k] = v[:, i]
    return z

reset_indexデータの一部としてインデックスを含む新しいデータフレームを作成するために使用します。そのデータフレームを構造体配列に変換します。

sa = df_to_sarray(df.reset_index())
sa

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

編集:python 3で.encode()を呼び出すエラーを回避するためにdf_to_sarrayを更新しました 。コメントと解決策を提供してくれたJoseph Garvinhalcyonに感謝します。


エラー:TypeError:データ型が不明
Joseph Garvin

あなたのコメントと訂正のためのハルシオンに感謝します。回答を更新しましたので、今すぐご利用いただければ幸いです。
Phil


5

サンプルDataFrameのより簡単な方法:

df

         gbm       nnet        reg
0  12.097439  12.047437  12.100953
1  12.109811  12.070209  12.095288
2  11.720734  11.622139  11.740523
3  11.824557  11.926414  11.926527
4  11.800868  11.727730  11.729737
5  12.490984  12.502440  12.530894

使用する:

np.array(df.to_records().view(type=np.matrix))

取得する:

array([[(0, 12.097439  , 12.047437, 12.10095324),
        (1, 12.10981081, 12.070209, 12.09528824),
        (2, 11.72073428, 11.622139, 11.74052253),
        (3, 11.82455653, 11.926414, 11.92652727),
        (4, 11.80086775, 11.72773 , 11.72973699),
        (5, 12.49098389, 12.50244 , 12.53089367)]],
dtype=(numpy.record, [('index', '<i8'), ('gbm', '<f8'), ('nnet', '<f4'),
       ('reg', '<f8')]))

4

データフレームからarcgisテーブルにエクスポートするときに同様の問題が発生し、usgs(https://my.usgs.gov/confluence/display/cdi/pandas.DataFrame+to+ArcGIS+Table)からのソリューションに出くわしました。要するに、あなたの問題は同様の解決策を持っています:

df

      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

np_data = np.array(np.rec.fromrecords(df.values))
np_names = df.dtypes.index.tolist()
np_data.dtype.names = tuple([name.encode('UTF8') for name in np_names])

np_data

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=(numpy.record, [('A', '<f8'), ('B', '<f8'), ('C', '<f8')]))

4

上記の答えを調べました。" as_matrix() "メソッドは機能しますが、現在は使用されていません。私にとって、うまくいったのは「.to_numpy()」でした。

これは多次元配列を返します。Excelシートからデータを読み取り、任意のインデックスからデータにアクセスする必要がある場合は、この方法を使用することをお勧めします。お役に立てれば :)


どういう意味ですか?任意のインデックスからデータにアクセスする必要がありますか?データの性質によっては、Pandas DataFrameはそもそも正しい選択ではない場合もあります。
AMC

2

流星の答えに加えて、私はコードを見つけました

df.index = df.index.astype('i8')

うまくいきません。だから私はこの問題で立ち往生している他の人の便宜のために私のコードをここに置いた。

city_cluster_df = pd.read_csv(text_filepath, encoding='utf-8')
# the field 'city_en' is a string, when converted to Numpy array, it will be an object
city_cluster_arr = city_cluster_df[['city_en','lat','lon','cluster','cluster_filtered']].to_records()
descr=city_cluster_arr.dtype.descr
# change the field 'city_en' to string type (the index for 'city_en' here is 1 because before the field is the row index of dataframe)
descr[1]=(descr[1][0], "S20")
newArr=city_cluster_arr.astype(np.dtype(descr))

1

データフレームをnumpy配列に変換する簡単な方法:

import pandas as pd
df = pd.DataFrame({"A": [1, 2], "B": [3, 4]})
df_to_array = df.to_numpy()
array([[1, 3],
   [2, 4]])

一貫性を保つために、to_numpyの使用をお勧めします。

リファレンス:https : //pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html


Arsamが提供するソリューションとあなたのソリューションの違いは何ですか...
qaiser

私が個人的に好むコード例を使用して、それをより完全かつ使いやすくしようとしました。
user1460675

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.