Как сопоставить уникальный номер каждой уникальной строке в столбце списков - PullRequest
0 голосов
/ 08 сентября 2018

В фрейме данных pandas у меня есть столбец, в котором каждая строка содержит список строк. Для каждой уникальной строки я хотел бы назначить уникальный номер.

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

Вот минимальный пример:

Настройка начального кадра данных панд

df = pd.DataFrame(data={'A': ['2f4', '1k1', 'nmk'], 'B': ['x', 'y', 'z']})
df.at[0, 'B'] = ['jki', 'gg4', 'k6k']
df.at[1, 'B'] = ['2f4', 'gg4', 'g24']
df.at[2, 'B'] = ['1k1', 'g24', '1k1']

будет выглядеть так

df

     A                B
0  2f4  [jki, gg4, k6k]
1  1k1  [2f4, gg4, g24]
2  nmk  [1k1, g24, 1k1]

Я ищу результат, похожий на

     A                B  MappedA    MappedB
0  2f4  [jki, gg4, k6k]        0  [3, 4, 5]
1  1k1  [2f4, gg4, g24]        1  [0, 4, 6]
2  nmk  [1k1, g24, 1k1]        2  [1, 6, 1]

Каждая строка имеет уникальный номер, начиная с 0. Если строка встречается снова, первый присвоенный номер используется снова.

Я нашел решения, в которых в столбце есть строка или число, например

Присвоение уникального идентификатора столбцу данных пандам.

Но я не смог найти решения, где столбец содержит список значений.

Edit:

Пояснение: длина списков в столбце b является переменной.

1 Ответ

0 голосов
/ 08 сентября 2018

pandas.factorize и numpy.split

i, u = pd.factorize([*df.A, *np.concatenate(df.B)])
l = df.B.str.len()[:-1].cumsum()
n = len(df)

df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))

     A                B  MappedA    MappedB
0  2f4  [jki, gg4, k6k]        0  [3, 4, 5]
1  1k1  [2f4, gg4, g24]        1  [0, 4, 6]
2  nmk  [1k1, g24, 1k1]        2  [1, 6, 1]

Объяснение

  1. разложить все столбцы 'A' и 'B' вместе
  2. найти длину списков в 'B', потому что они помогут определить, где разбить результирующий массив
  3. Возьмите первый n, принадлежащий 'MappedA'
  4. Возьмите остаток и разделите в соответствии с рассчитанными длинами.

Переменная длина

Предположим, у нас было это df вместо

df = pd.DataFrame(data={'A': ['2f4', '1k1', 'nmk'], 'B': ['x', 'y', 'z']})
df.at[0, 'B'] = ['jki', 'gg4', 'k6k']
df.at[1, 'B'] = ['2f4', 'gg4', 'g24']
df.at[2, 'B'] = ['1k1', 'g24', '1k1', 'pir']

df

     A                     B
0  2f4       [jki, gg4, k6k]
1  1k1       [2f4, gg4, g24]
2  nmk  [1k1, g24, 1k1, pir]

Тогда то же решение приводит к

i, u = pd.factorize([*df.A, *np.concatenate(df.B)])
l = df.B.str.len()[:-1].cumsum()
n = len(df)

df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))

     A                     B  MappedA       MappedB
0  2f4       [jki, gg4, k6k]        0     [3, 4, 5]
1  1k1       [2f4, gg4, g24]        1     [0, 4, 6]
2  nmk  [1k1, g24, 1k1, pir]        2  [1, 6, 1, 7]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...