それを行うにはいくつかの方法がありますが、いくつかは他よりもきれいです。
通常、numpyでは、文字列データを別の配列に保持します。
(たとえば、Rのデータフレームよりも少し低レベルです。通常は、関連付けのためにクラスにまとめるだけですが、異なるデータ型は別々に保持します。)
正直なところ、numpyはこのような「柔軟な」データ型を処理するために最適化されていません(確かにそれは可能ですが)。「スプレッドシートのような」データのためのより良いインターフェースを提供するようなものですpandas
(そしてパンダはnumpyの上にある単なるレイヤーです)。
ただし、構造化配列(ここにあるもの)を使用すると、フィールド名のリストを渡すときに列ごとにスライスできます。(例data[['col1', 'col2', 'col3']]
)
とにかく、1つの方法は次のようなことをすることです:
import numpy as np
data = np.recfromcsv('iris.csv')
# In this case, it's just all but the last, but we could be more general
# This must be a list and not a tuple, though.
float_fields = list(data.dtype.names[:-1])
float_dat = data[float_fields]
# Now we just need to view it as a "regular" 2D array...
float_dat = float_dat.view(np.float).reshape((data.size, -1))
# And we can normalize columns as usual.
normalized = (float_dat - float_dat.min(axis=0)) / float_dat.ptp(axis=0)
ただし、これは理想からはほど遠いです。(現在のように)インプレースで操作を実行する場合、最も簡単な解決策は、すでに持っているものです。フィールド名を繰り返すだけです。
ちなみに、を使用するpandas
と、次のようになります。
import pandas
data = pandas.read_csv('iris.csv', header=None)
float_dat = data[data.columns[:-1]]
dmin, dmax = float_dat.min(axis=0), float_dat.max(axis=0)
data[data.columns[:-1]] = (float_dat - dmin) / (dmax - dmin)