Есть несколько способов сделать это, но некоторые чище, чем другие.
Обычно в numpy строковые данные хранятся в отдельном массиве.
(Вещи немного более низкого уровня, чем, скажем, фрейм данных R. Обычно вы просто заключаете вещи в класс для ассоциации, но разделяете разные типы данных.)
Честно говоря, numpy не оптимизирован для обработки таких "гибких" типов данных (хотя, безусловно, он может это делать). Такие вещи, как pandas
обеспечивают лучший интерфейс для данных, подобных «электронным таблицам» (а pandas - это просто слой поверх numpy).
Однако, структурированные массивы (что у вас есть здесь) позволят вам разрезать их по столбцам, когда вы передадите список имен полей. (например, data[['col1', 'col2', 'col3']]
)
В любом случае, один из способов сделать что-то вроде этого:
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)