Строковые данные в списке в числовые значения в Python |неприемлемый тип: 'список' - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть следующий список, это огромный список, это всего лишь кусок.

 my_list= [['I. R. Palmer','U. Kersten'],
           ['H. Breitwieser', 'U. Kersten'],
           ['Halvard Skogsrud', 'Boualem Benatallah', 'Fabio Casati', 'Manh Q. Dinh'],
           ['Stefano Ceri', 'Piero Fraternali', 'Stefano Paraboschi']]

Я хочу назначить каждой строке в списке уникальное числовое значение.если строка повторяет где-то еще, присвойте ей то же самое предыдущее значение

new_list= [[0,1],
           [2,1],
           [3,4,5,6],
           [7,8,9]]

я пробовал

pd.factorize(my_list)

но я получаю

unhashable type: 'list'

Ответы [ 4 ]

0 голосов
/ 13 декабря 2018

factorize + concatenate + cumsum + array_split

pd.factorize работает путем хеширования.Но значения в ваших списках являются списками , которые не могут быть хэшируемыми.Действительно, в любом случае вы ищете не хэш-списки, а отдельные значения.

Вместо этого вы можете разложить список сглаженный и использовать массив индексов для разбиения:

import pandas as pd
import numpy as np

flattened = np.concatenate(my_list)
idx_split = np.array(list(map(len, my_list))).cumsum()[:-1]

res = [i.tolist() for i in np.array_split(pd.factorize(flattened)[0], idx_split)]

print(res)

[[0, 1], [2, 1], [3, 4, 5, 6], [7, 8, 9]]
0 голосов
/ 13 декабря 2018

Вы можете иметь только 1-D последовательность в pd.factorize.См. doc

. Вы можете использовать np.concatenate для преобразования списка в 1D

import numpy as np
print(np.concatenate(my_list))
# array(['I. R. Palmer', 'U. Kersten', 'H. Breitwieser', 'U. Kersten',
#   'Halvard Skogsrud', 'Boualem Benatallah', 'Fabio Casati',
#   'Manh Q. Dinh', 'Stefano Ceri', 'Piero Fraternali',
#   'Stefano Paraboschi'], dtype='<U18')

print(pd.factorize(np.concatenate(my_list)))

Вывод:

(array([0, 1, 2, 1, 3, 4, 5, 6, 7, 8, 9], dtype=int64),
 array(['I. R. Palmer', 'U. Kersten', 'H. Breitwieser', 'Halvard Skogsrud',
        'Boualem Benatallah', 'Fabio Casati', 'Manh Q. Dinh',
        'Stefano Ceri', 'Piero Fraternali', 'Stefano Paraboschi'],
       dtype=object))
0 голосов
/ 13 декабря 2018

Вы можете сгладить список, использовать factorize, работая с массивом 1d, создать dict с помощью zip и заменить в понимании вложенного списка:

a = [y for x in my_list for y in x]
f1, f2 = pd.factorize(a)
d = dict(zip(f2[f1], f1))

new_list = [[d[y] for y in x] for x in my_list]
print (new_list)
[[0, 1], [2, 1], [3, 4, 5, 6], [7, 8, 9]] 
0 голосов
/ 13 декабря 2018

pandas.factorize работает с одномерной последовательностью, но у вас есть двумерная последовательность.А поскольку ваша 2D-последовательность не является правильной формой (каждый внутренний список имеет разную длину), вы не сможете обойти эту проблему путем изменения формы.Ошибка, которую вы видите, состоит в том, что pandas пытается рассматривать внутренние списки как категории, а не как строки внутри внутренних списков.

Вы можете построить результат самостоятельно:

authors_map = {}  # I'm just guessing that they're authors
next_id = 0
new_list = []
for authors in my_list:
    new_authors = []
    for author in authors:
        if author not in authors_map:
            authors_map[author] = next_id
            next_id += 1
        new_authors.append(authors_map[author])
    new_list.append(new_authors)
...