Как мне прочитать CSV-файл, используя Pandas, а затем разделить столбцы на два Numpy массива, используя to_ numpy для Scikit-Learn? - PullRequest
2 голосов
/ 04 февраля 2020

В итоге я хочу, чтобы функция Python 3:

  1. считывала данные из CSV-файла, разделенного табуляцией
  2. возвращала кортеж из двух частей, где обе части numpy массивы (примеры ниже):
    • первая часть - это все данные из всех столбцов , за исключением первого столбца, с каждая строка является собственным списком ( 2-мерная матрица)
    • вторая часть кортежа - это все данные из первого столбца в виде списка (или это одномерный массив?)
  3. на данный момент сохраняют правильные типы для каждого элемента данных, либо строковые, либо целочисленные

Два массива Numpy должны быть переданы в Scikit-Learn, в частности Id3Estimator.fit

Проблемы, с которыми я столкнулся:

  1. Я новичок в Python
  2. Я совершенно новичок в numpy, pandas и Scikit-learn
  3. Многие из примеров, которые я могу найти, либо тривиально просты и не соответствуют моим потребностям, либо неосуществимо сложны для eginner
  4. В некоторых ответах, которые я нашел в StackExchange, используются устаревшие методы .to_matrix и .values, но я хочу быть в курсе

CSV

Данные CSV неоднородны. Первый столбец - это классификация, остальные - данные объекта:

(30k,38k)   45  male    private m
(30k,38k)   50  female  private m
(30k,38k)   61  other   public  b
(13k,15k)   40  male    private none
(23k,30k)   34  other   private b

Данные второго столбца (которые я обнаружил, пронумерованы 1 из-за 0-индексации) все целые числа. Все остальные столбцы полностью строковые.

Структуры данных

ID3Estimator поставляется с примером аппаратных данных, и я хочу адаптировать его для чтения из файла CSV, разделенного табуляцией. Встроенные данные имеют 3 явные структуры данных:

  1. имена элементов (которые я успешно прочитал из отдельного файла)
  2. instances, которые выглядят так:
np.array([[45, "male", "private", "m"],
          [50, "female", "private", "m"],
          [61, "other", "public", "b"],
          [40, "male", "private", "none"],
          [34, "other", "private", "b"]])
classifications, которые выглядят так:
np.array(["(30k,38k)",
          "(30k,38k)",
          "(30k,38k)",
          "(13k,15k)",
          "(23k,30k)"])

Я использовал import numpy as np

Минимальный почти рабочий пример

import numpy as np
import pandas as pd
from id3 import Id3Estimator

def read_instances():
    """ returns (instances, classifications)
    """
    data = pd.read_csv('data.csv',
                       dtype=str, # UPDATE (see below)
                       header=None,
                       sep='\t')
    # iloc[rows, column(s)] where : means "all"
    return np.array(data.iloc[:, 1:]),\
           np.array(list(data.iloc[:, 0]))
# the first part of the return seems to be incorrect

instances, classifications = read_instances()

clf = Id3Estimator()
clf.fit(instances, classifications, check_input=True)

Биты, которые работают

  1. Все данные считываются правильно
  2. Массив classifications отображается в правильном формате

Неработающие биты

  1. Неправильный массив instances

Трассировка ошибок:

    clf.fit(instances, classifications, check_input=True)
  File "\Python38\lib\site-packages\id3\id3.py", line 92,
    in fit
    X_, y_ = check_X_y(X, y)
  File "D:\_tools\Python38\lib\site-packages\sklearn\utils\validation.py", line 747,
    in check_X_y
    X = check_array(X, accept_sparse=accept_sparse,
  File "\Python38\lib\site-packages\sklearn\utils\validation.py", line 531,
    in check_array
    array = np.asarray(array, order=order, dtype=dtype)
  File "\Python38\lib\site-packages\numpy\core\_asarray.py", line 85,
    in asarray
    return array(a, dtype, copy=False, order=order)
ValueError: could not convert string to float: 'male'

Существует также множество предупреждений об устаревании, связанных с six.py, которые я не включил. Я предполагаю, что это что-то в библиотеке id3.

Я бы не удивился, если бы что-то действительно простое я пропустил, и не удивлюсь, если весь мой подход неверен. Я не уверен, что использование list для создания одномерного массива для classifications - это «правильный» способ сделать это. Что касается части instances, я чувствую, что хочу объединить pandas.DataFrame.to_numpy со срезом массива, но я в настоящее время слишком запутался, и мне и моей резиновой утке было достаточно отладки.

Любопытно, что аппаратный код не требует явного указания типов. Я видел что-то о dtype или что-то подобное где-то, но сейчас я насыщен Я устал после дня установки python и библиотек (через обновление pip), пытаясь выяснить обработку параметров командной строки (до argparse в конечном итоге после долгого getopt wild- goose chase), пытаясь выяснить, как импортировать CSV против импорта Panda CSV, и возникла путаница с параметрами iloc и обозначениями срезов массива.

Update 1

Я распечатал np.array зашитой версии:

[['45' 'male' 'private' 'm']
 ['50' 'female' 'private' 'm']
.
.
.
['34' 'other' 'private' 'b']]

и версии, поступающей из CSV через read_instances ():

[[45 'male' 'private' 'm']
 [50 'female' 'private' 'm']
.
.
.
 [34 'male' 'private' 'b']

и заметил, что в последней (нерабочей) версии что числа являются числами, тогда как они являются строками в аппаратной версии. Я нахожу это странным, потому что они не указаны в жесткой версии. Поэтому я добавил dtype=str к pd.read_csv(), который обрабатывает числа как строки.

Так что теперь, когда я печатаю две версии np.array, они печатаются одинаково. Однако он по-прежнему выдает ту же ошибку ValueError: could not convert string to float: 'male', вероятно, по той же причине (ам), что и до изменения.

Обновление 2

Я получил ее, добавив dtype=str к np.array call:

def read_instances():
    """ returns (instances, classifications)
    """
    data = pd.read_csv(args['instances'],
                       dtype=str, # makes everything strings
                       header=None,
                       sep='\t')
    # iloc[rows, column(s)] where : means "all"
    return np.array(data.iloc[:, 1:], dtype=str),\
           np.array(list(data.iloc[:, 0]))

Но я все равно хотел бы знать, является ли способ чтения файла CSV и разбиения столбцов «лучшим» способом сделать это, где «лучшее» может быть «самый элегантный» или «самый эффективный» Мы должны предположить, что файл CSV не слишком большой, чтобы поместиться в память, потому что если бы он был, я не понимаю, как можно загрузить его для обучения алгоритму машинного обучения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...