熊猫:遍历行并为值赋予唯一编号

时间:2020-04-06 09:34:22

标签: python pandas dataframe sorting uniqueidentifier

您好,Stackoverflow的朋友们。我很乐意为遇到的问题提供一些指导。那是我寻求帮助的部分,因为我的新手知识不足以帮助我。

简而言之:我拥有大量的数据,并且想知道如何为这些值提供一个唯一的编号以标识它们。但是没有几次,只有一次。

我们拥有什么和想要的东西

  • 2列:A和B
  • 大约200行。其中一些是重复项。我只发布一个子集。
  • 值可以(但不是必须)同时出现在A列和B列中。如果出现,则它可能会发生多次:也许只是一次到几次。
  • 每个值只能给一个数字一次。这很重要。
  • 以“ EB”开头的值应从300开始给数字。下一个“ EB”值301等。
  • 以'IN'开头的值应从400开始给数字。下一个'IN'值401等。
  • 每个不以'EB'或'IN'开头的值都应从500开始。
  • 我希望在同一DataFrame中拥有它。名称为“ C”和“ D”的列中的每个EB值,名称为“ E”和“ F”的列中的每个“ IN”值及其编号,以及列“ 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

我想要的(输出)

Click me. Every value has been given an unique number!

我的想法(我未能实现该想法)

  • 遍历A和B列,将以“ EB”开头的不同值复制到数组中。
  • 第二个数组,用于以'IN'开头的不同值。 (就像上面没有名称相同的字符串一样)
  • 不是 的每个以'EB'或'IN'开头的值的第三个数组。
  • 可以在这三个数组中的每个数组上应用的函数:从给定值(例如300)开始,遍历数组中的每个项目,然后将它们写入自己的列中。它旁边的数字是其自己的列,列表中的每个项目都将+1递增。只要数组的长度。

我希望这篇文章不要太长。我为能在这里获得的所有帮助感到高兴。

1 个答案:

答案 0 :(得分:0)

这将为您提供所需的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)

Example code in Python Tutor

edit:如下图所示,用df_300循环替换df_400df_500for的三个列表伴奏可能是最佳选择。仅当您要分配大量代码的唯一值时,这种速度的提高才会显着,如果是这种情况,您可能希望代码成千上万而不是数百:

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)

Example 2 code in python tutor