Pandas: перебирать строки и присваивать значениям уникальный номер - PullRequest
1 голос
/ 06 апреля 2020

Здравствуйте, дорогие люди из Stackoverflow. Я бы хотел получить руководство по проблеме, от которой у меня болит голова. Это та часть, где я прошу помощи, поскольку мои знания новичка не помогают мне в этом.

Короче говоря: у меня есть набор огромного количества данных, и я хотел бы знать, как я может дать этим значениям уникальный номер для их идентификации. Но не несколько, а только один раз.

Что у нас есть и что нужно :

  • 2 Столбцы: A и B
  • Около 200 рядов. Некоторые из них являются дубликатами. Я только собираюсь опубликовать подмножество.
  • Значения могут (но не должны) появляться в обоих столбцах A и B. Если, то это может происходить несколько раз: возможно, от одного до нескольких раз.
  • Каждому значению должен быть присвоен номер только один раз. Это важно.
  • Значениям, начинающимся с 'EB', следует давать числа, начинающиеся с 300. Следующее значение 'EB' 301, et c.
  • Значения, начинающиеся с 'IN' должны быть заданы числа, начинающиеся с 400. Следующее значение 'IN' 401 и т. д. c.
  • Каждому значению, которое не начинается с 'EB' или 'IN', должны быть присвоены числа, начинающиеся с 500.
  • Я бы хотел, чтобы это было в одном и том же DataFrame. Каждое EB-значение с его номером в столбце с именами 'C' и 'D', каждое 'IN' -значение с его номером в столбце с именами 'E' и 'F' и все остальное в столбец 'G' и 'H'.

Ввод :

d = {
'A': ['Rack Ants', 'EB Animals', 'IN Penguin', 'IN Penguin', 'IN Hippo', 'T-IPS-ACK', 'AA-BMUL', 'VB-SEM-012', 'VE-PAG'], 
'B': ['EB Animals', 'Applications', 'EB Animals', 'EB Animals', 'EB Humans', 'Applications', 'IN Penguin', 'IN Hippo', 'IN Crocodile']
}
df = pd.DataFrame(data=d)
df

Что я хотел бы иметь (Вывод) :

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

Моя идея (мне не удалось это реализовать) :

  • Перебирать столбцы A и B, скопируйте различные значения с началом 'EB' в массив.
  • Второй массив для различных значений, начинающихся с 'IN'. (Как и выше, нет строк с одинаковыми именами)
  • Третий массив для каждого значения, которое не равно , начиная с 'EB' или 'IN'.
  • Функция который может быть применен к каждому из этих трех массивов: начиная с заданного значения (например, 300), просматривая каждый элемент в массиве, записывая их в свой собственный столбец. Рядом с ним будет номер в собственном столбце, увеличенный +1 для каждого элемента в списке. Пока длина массива.

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

1 Ответ

0 голосов
/ 06 апреля 2020

Это даст вам DataFrame, который вам нужен. По большей части вы были осведомлены о том, что вам нужно было сделать, чтобы решить эту проблему:

import pandas as pd

def buld_key_df(values:list, number:int) -> pd.DataFrame:
    return pd.DataFrame({
        f'name ({number}s)' : values,
        f'code ({number}s)' : [number + i for i in range(len(values))],
    })

df = pd.DataFrame({
    'A': [
        'Rack Ants', 'EB Animals', 'IN Penguin', 
        'IN Penguin', 'IN Hippo', 'T-IPS-ACK', 
        'AA-BMUL', 'VB-SEM-012', 'VE-PAG'
    ], 
    'B': [
        'EB Animals', 'Applications', 'EB Animals', 
        'EB Animals', 'EB Humans', 'Applications', 
        'IN Penguin', 'IN Hippo', 'IN Crocodile'
    ],
})

unique = pd.concat([df['A'],df['B']]).unique()

df_300 = [x for x in unique if x.startswith('EB ')]
df_400 = [x for x in unique if x.startswith('IN ')]
df_500 = [x for x in unique if x not in df_300 + df_400]

df_300 = buld_key_df(df_300, 300)
df_400 = buld_key_df(df_400, 400)
df_500 = buld_key_df(df_500, 500)

df = pd.concat([df, df_300, df_400, df_500], axis=1).fillna('')

pd.set_option('display.max_columns', 8)
print(df)

Пример кода в Python Репетитор

Редактировать: It может быть более оптимальным заменить три списка для df_300, df_400 и df_500 на for l oop, как показано ниже. Это увеличение скорости будет заметно только в том случае, если у вас есть огромное количество уникальных значений, которым вы назначаете коды, и если это так, вы, вероятно, захотите, чтобы коды составляли десятки тысяч, а не сотни:

import pandas as pd

def buld_key_df(values:list, number:int) -> pd.DataFrame:
    return pd.DataFrame({
        f'name ({number}s)' : values,
        f'code ({number}s)' : [number + i for i in range(len(values))],
    })

df = pd.DataFrame({
    'A': [
        'Rack Ants', 'EB Animals', 'IN Penguin', 
        'IN Penguin', 'IN Hippo', 'T-IPS-ACK', 
        'AA-BMUL', 'VB-SEM-012', 'VE-PAG'
    ], 
    'B': [
        'EB Animals', 'Applications', 'EB Animals', 
        'EB Animals', 'EB Humans', 'Applications', 
        'IN Penguin', 'IN Hippo', 'IN Crocodile'
    ],
})

unique = pd.concat([df['A'],df['B']]).unique()

df_30k, df_40k, df_50k = [], [], []

for x in unique:
    if x.startswith('EB '):
        df_30k.append(x)
    elif x.startswith('IN '):
        df_40k.append(x)
    else:
        df_50k.append(x)

df_30k = buld_key_df(df_30k, 30000)
df_40k = buld_key_df(df_40k, 40000)
df_50k = buld_key_df(df_50k, 50000)

df = pd.concat([df, df_30k, df_40k, df_50k], axis=1).fillna('')

pd.set_option('display.max_columns', 8)
print(df)

Пример 2 кода в python tutor

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...