Как преобразовать все значения столбца в уникальные целые числа? - PullRequest
0 голосов
/ 16 июня 2020

Я работаю над набором шахматных данных, где у меня есть столбец для move_1, move_2, move_3 и так далее ... в каждом из этих столбцов есть «игровой код», созданный игроком. Каждая строка предназначена для определенной c игры, и их около 1000 строк.

  result move_1 move_2 move_3 ...
      1     e4     d4    Nc3  ...    
      1     d4    Nf3     c4  ...
      1     e4     d3    Nd2  ...
      1     d4     c4     d5  ...
      0     d4     c4    Nc3  ...

keeps going down...

как мне лучше всего изменить каждое уникальное значение в каждой строке / столбце на назначенное целое число, чтобы я мог провести анализ? Я сделал следующее:

chess_df['move_2'].replace(to_replace=['Nf3', 'c4', 'd3','d4', 'Nc3'],
           value= [3, 2, 4, 1, 7],
           inplace=True)

, где каждому «игровому коду» присвоено целое число. Итак, 'd4' = 1, 'c4 = 2 и так далее, во ВСЕХ строках .

Проблема в том, что это НЕ лучший способ сделать это, поскольку мне нужно найти каждую и каждый уникальный код и замените его на уникальное целое число столбцами ... Это займет много времени, и это будет действительно запутать.

Я хочу, чтобы столбец move_1 имел 1000 строк и 45 уникальных игровых кодов '. Таким образом, каждый игровой код в нем стал бы числом от 1 до 45.

Столбец move_2 имеет 1000 строк с 89 уникальными значениями, 25 из которых также находятся в столбце move_1. Поэтому мне нужно назначить 25 номеров, уже назначенных в столбце move_1 + 64 новые номера. И так далее ...

Итак, мой вопрос:

Как я могу с помощью кода Python создать что-то, что автоматизирует процесс изменения 'play code 'в уникальное целое число для всех строк и столбцов?

Ответы [ 4 ]

1 голос
/ 16 июня 2020

Это помогает?

unique_vals = chess_df['move_2'].unique()
chess_df['move_2'].replace(to_replace=unique_vals,
           value= list(range(len(unique_vals))),
           inplace=True)
0 голосов
/ 16 июня 2020

В этом ответе учитываются все ходы в move_1, затем move_2 и так далее (я предполагаю, что именно так вы описали в вопросе) и находит уникальные ходы во ВСЕХ ходах в указанном порядке и присваивает им целочисленные значения:

moves = chess_df.loc[:,chess_df.columns!='result'].stack().sort_index(level=1).unique()
chess_df.replace(to_replace=moves,value=list(range(len(moves))),inplace=True)  

Другими словами, он сначала присваивает целые числа move_1, затем move_2 (с учетом повторений) и т. Д.

ввод / вывод для рассматриваемого примера:

   result move_1 move_2 move_3
0       1     e4     d4    Nc3
1       1     d4    Nf3     c4
2       1     e4     d3    Nd2
3       1     d4     c4     d5
4       0     d4     c4    Nc3

   result  move_1  move_2  move_3
0       1       0       1       5
1       1       1       2       4
2       1       0       3       6
3       1       1       4       7
4       0       1       4       5
0 голосов
/ 16 июня 2020

Это был бы мой подход:

import pandas as pd
df = pd.DataFrame({'Move_1':['a1','b2','c3','c4'],
                   'Mode_2':['a1','f5','h6','b2']})

replacers = {k:list(set([x[0] for x in df.values.reshape(-1,1)])).index(k) for k in list(set([x[0] for x in df.values.reshape(-1,1)]))}
df_new = df.replace(replacers)

Вывод:

   Move_1  Mode_2
0       0       0
1       5       3
2       1       4
3       2       5

По сути, мы создаем словарь с шахматными позициями в качестве ключа и уникальным числом в качестве значения. Затем это будет использоваться в df.replace() для выполнения замены всех значений в df.

0 голосов
/ 16 июня 2020

Простая альтернатива - сложить все в одну серию, ранжировать ее, а затем разложить обратно. Таким образом, рейтинг применяется ко всему DataFrame. Здесь d4 становится 6 независимо от того, где оно встречается.

df.filter(like='move_').stack().rank(method='dense').atype(int).unstack()
#   move_1  move_2  move_3
#0       8       6       1
#1       6       3       4
#2       8       5       2
#3       6       4       7
#4       6       4       1

В качестве альтернативы вы можете использовать аргумент return_inverse из np.unique и заново создать DataFrame.

arr = df.filter(like='move')
pd.DataFrame(np.unique(arr, return_inverse=True)[1].reshape(arr.shape),
             index=arr.index,
             columns=arr.columns)

#   move_1  move_2  move_3
#0       7       5       0
#1       5       2       3
#2       7       4       1
#3       5       3       6
#4       5       3       0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...