Преобразование структурированного массива в массив numpy для использования с Scikit-Learn

мне трудно преобразовать структурированный массив, загруженный из CSV, используя np.genfromtxt на np.array для того, чтобы соответствовать данным в Scikit-Learn оценки. Проблема в том, что в какой-то момент произойдет приведение из структурированного массива в регулярный массив, в результате чего ValueError: can't cast from structure to non-structure. Долгое время я использовал .view для выполнения преобразования, но это привело к ряду предупреждений об устаревании от NumPy. Код выглядит следующим образом:

import numpy as np
from sklearn.ensemble import GradientBoostingClassifier

data = np.genfromtxt(path, dtype=float, delimiter=',', names=True)

target = "occupancy"
features = [
    "temperature", "relative_humidity", "light", "C02", "humidity"
]

# Doesn't work directly
X = data[features]
y = data[target].astype(int)

clf = GradientBoostingClassifier(random_state=42)
clf.fit(X, y)

за исключением поднимается: ValueError: Can't cast from structure to non-structure, except if the structure only has a single field.

моя вторая попытка заключалась в следующем:

# View is raising deprecation warnings
X = data[features]
X = X.view((float, len(X.dtype.names)))
y = data[target].astype(int)

который работает и делает именно то, что я хочу (мне не нужна копия данных), но приводит к предупреждениям об устаревании:

FutureWarning: Numpy has detected that you may be viewing or writing to 
an array returned by selecting multiple fields in a structured array.

This code may break in numpy 1.15 because this will return a view 
instead of a copy -- see release notes for details.

на данный момент мы используем tolist() преобразовать структурированный массив в список, а затем в np.array. Это работает, однако кажется ужасно неэффективным:

# Current method (efficient?)
X = np.array(data[features].tolist())
y = data[target].astype(int)

там должен быть лучший способ, я ценю любые советы.

Примечание: данные для этого примера от репозиторий занятости UCI ML и данные появляются следующим образом:

array([(nan, 23.18, 27.272 , 426.  ,  721.25, 0.00479299, 1.),
       (nan, 23.15, 27.2675, 429.5 ,  714.  , 0.00478344, 1.),
       (nan, 23.15, 27.245 , 426.  ,  713.5 , 0.00477946, 1.), ...,
       (nan, 20.89, 27.745 , 423.5 , 1521.5 , 0.00423682, 1.),
       (nan, 20.89, 28.0225, 418.75, 1632.  , 0.00427949, 1.),
       (nan, 21.  , 28.1   , 409.  , 1864.  , 0.00432073, 1.)],
      dtype=[('datetime', '<f8'), ('temperature', '<f8'), ('relative_humidity', '<f8'), 
             ('light', '<f8'), ('C02', '<f8'), ('humidity', '<f8'), ('occupancy', '<f8')])

2 ответов


добавить .copy() to data[features]:

X = data[features].copy()
X = X.view((float, len(X.dtype.names)))

и FutureWarning сообщение ушло.

это должно быть более эффективным, чем преобразование в список первым.


вы можете избежать необходимости копирования, если вы можете сначала прочитать данные в простой массив NumPy (опустив