Pandas:遍历行并为值赋一个唯一的数字

问题描述 投票:0回答:1

您好,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。只要数组的长度。

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

python pandas dataframe sorting uniqueidentifier
1个回答
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

编辑:最好用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

© www.soinside.com 2019 - 2024. All rights reserved.