Я пытаюсь написать функцию, которая превращает все нечисловые столбцы в наборе данных в числовую форму.

Набор данных представляет собой список списков.

Вот мой код:

def handle_non_numerical_data(data):
    def convert_to_numbers(data, index):
        items = []
        column = [line[0] for line in data]
        for item in column:
            if item not in items:
                items.append(item)
        [line[0] = items.index(line[0]) for line in data]
        return new_data

    for value in data[0]:
        if isinstance(value, str):
            convert_to_numbers(data, data[0].index(value))

Очевидно, [line[0] = items.index(line[0]) for line in data] не является допустимым синтаксисом, и я не могу понять, как изменить первый столбец данных при его итерации.

Я не могу использовать NumPy, потому что данные не будут в числовой форме, пока не будет запущена эта функция.

Как мне это сделать и почему это так сложно? Я чувствую, что это должно быть намного проще, чем есть ...

Другими словами, я хочу включить это:

[[M,0.455,0.365,0.095,0.514,0.2245,0.101,0.15,15],
[M,0.35,0.265,0.09,0.2255,0.0995,0.0485,0.07,7],
[F,0.53,0.42,0.135,0.677,0.2565,0.1415,0.21,9]]

В это:

[[0,0.455,0.365,0.095,0.514,0.2245,0.101,0.15,15],
[0,0.35,0.265,0.09,0.2255,0.0995,0.0485,0.07,7],
[1,0.53,0.42,0.135,0.677,0.2565,0.1415,0.21,9]]

Обратите внимание, что первый столбец был изменен со строк на числа.

0
Matt 9 Янв 2017 в 19:38

3 ответа

Лучший ответ

Решение

data = [['M',0.455,0.365,0.095,0.514,0.2245,0.101,0.15,15],
        ['M',0.35,0.265,0.09,0.2255,0.0995,0.0485,0.07,7],
        ['F',0.53,0.42,0.135,0.677,0.2565,0.1415,0.21,9]]

values = {'M': 0, 'F': 1}

new_data = [[values.get(val, val) for val in line] for line in data]
new_data

Выход:

[[0, 0.455, 0.365, 0.095, 0.514, 0.2245, 0.101, 0.15, 15],
 [0, 0.35, 0.265, 0.09, 0.2255, 0.0995, 0.0485, 0.07, 7],
 [1, 0.53, 0.42, 0.135, 0.677, 0.2565, 0.1415, 0.21, 9]]

Объяснение

Вы можете воспользоваться словарями Python и их методом get.

Это значения для строк:

values = {'M': 0, 'F': 1}

Вы также можете добавить больше строк, таких как I с соответствующим значением.

Если строка values, вы получите значение из dict:

>>> values.get('M', 'M')
0 

В противном случае вы получите исходное значение:

>>> values.get(10, 10)
10
1
Mike Müller 9 Янв 2017 в 17:12

Вместо того, чтобы индексировать (что я не уверен, как это должно было работать в вашем примере), вы можете вместо этого создать сопоставление словаря для букв в числа. Нечто подобное должно работать.

raw_data = [['M',0.455,0.365,0.095,0.514,0.2245,0.101,0.15,15],
            ['M',0.35,0.265,0.09,0.2255,0.0995,0.0485,0.07,7],
            ['F',0.53,0.42,0.135,0.677,0.2565,0.1415,0.21,9]]

def handle_non_numerical_data(data):
    mapping = {'M': 0, 'F': 1, 'I': 2}

    for item in raw_data:
        if isinstance(item[0], str):
            item[0] = mapping.get(item[0], -1) # Returns -1 if letter not found
    return data

run = handle_non_numerical_data(raw_data)
print(run)
0
roganjosh 9 Янв 2017 в 16:53

В этом ответе будет использоваться dict для хранения кода от str до int. Его можно предварительно загрузить, а также исследовать после замены данных.

# MODIFIES DATA IN PLACE
data = [['M',0.455,0.365,0.095,0.514,0.2245,0.101,0.15,15],
        ['M',0.35,0.265,0.09,0.2255,0.0995,0.0485,0.07,7],
        ['F',0.53,0.42,0.135,0.677,0.2565,0.1415,0.21,9]]

coding_dict = {} # can also preload this {'M': 0, 'F':1}
for row in data:
    if row[0] not in coding_dict:
        coding_dict[row[0]] = len(coding_dict)
    row[0] = coding_dict[row[0]]
0
Logan Byers 9 Янв 2017 в 17:29