Python: как назначить уникальные идентификаторы записям фрейма данных pandas

У меня есть такой дафараме:

df
    Name1   Name2
0   John    Jack
1   John    Albert
2   Jack    Eva
3   Albert  Sara
4   Eva     Sara

Я хочу присвоить каждому уникальное имя ID. Так:

df
    Name1   Name2      ID1     ID2
0   John    Jack        0       1
1   John    Albert      0       2
2   Jack    Eva         1       3
3   Albert  Sara        2       5
4   Eva     Sara        3       5

Важно ли какое имя получит какой номер?

timgeb 07.01.2019 12:40

Нет, это не важно. Просто уникальные идентификаторы от 0 до 1

emax 07.01.2019 12:41
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
2
95
2

Ответы 2

Сначала сгладьте значения с помощью numpy.ravel и измените форму с помощью исходного df, используйте конструктор DataFrame и создайте имена столбцов, последний join в исходный:

df1 = pd.DataFrame(pd.factorize(df.values.ravel())[0].reshape(df.shape))
df1.columns = ['ID{}'.format(x+1) for x in range(len(df1.columns))]
print (df1)
   ID1  ID2
0    0    1
1    0    2
2    1    3
3    2    4
4    3    4

df = df.join(df1)
print (df)
    Name1   Name2  ID1  ID2
0    John    Jack    0    1
1    John  Albert    0    2
2    Jack     Eva    1    3
3  Albert    Sara    2    4
4     Eva    Sara    3    4

Создайте MultiIndex Series с помощью stack, создайте id с помощью factorize и для DataFrameunstack, затем столбцы rename и добавьте к оригиналу с помощью join:

s = df.stack()
df = df.join(pd.Series(pd.factorize(s)[0], index=s.index)
               .unstack()
               .rename(columns=lambda x: x.replace('Name','ID')))
print (df)
    Name1   Name2  ID1  ID2
0    John    Jack    0    1
1    John  Albert    0    2
2    Jack     Eva    1    3
3  Albert    Sara    2    4
4     Eva    Sara    3    4

Аналогичная альтернатива:

s = df.stack()
s[:] = pd.factorize(s)[0]
df = df.join(s.unstack().rename(columns=lambda x: x.replace('Name','ID')))
print (df)
    Name1   Name2  ID1  ID2
0    John    Jack    0    1
1    John  Albert    0    2
2    Jack     Eva    1    3
3  Albert    Sara    2    4
4     Eva    Sara    3    4

Альберт получает 2 в вашем решении в обоих столбцах. OP указывал 2 и 4.

timgeb 07.01.2019 12:45

@timgeb - да, заметил, надеюсь это опечатка. Похоже на то.

jezrael 07.01.2019 12:47

Если не важно, какое имя получит какое число, вы также можете рассмотреть

df.join(df.stack().astype('category').cat.codes.unstack() 
          .rename(columns=lambda c: c.replace('Name', 'ID')))                                                                  

который производит

    Name1   Name2  ID1  ID2
0    John    Jack    3    2
1    John  Albert    3    0
2    Jack     Eva    2    1
3  Albert    Sara    0    4
4     Eva    Sara    1    4

Другие вопросы по теме