Pandas:遍历行并给值一个唯一的数字
Pandas: Iterate over rows and give values an unique number
大家好,亲爱的 Whosebug 用户。我很想就一个让我头疼的问题得到一些指导。这就是我寻求帮助的部分,因为我的新手知识并不能帮助我解决这个问题。
简而言之:我有一组大量的数据,想知道如何给这些值一个唯一的数字来识别它们。但不是几次,只有一次。
我们有什么,想要什么:
- 2 列:A 和 B
- 大约 200 行。其中一些是重复的。我只会 post 一个子集。
- 值可以(但不是必须)同时出现在 A 列和 B 列中。如果出现,那么它可能会出现多次:可能只是一次或多次。
- 每个值只能指定一个数字一次。这很重要。
- 以'EB'开头的值应从300开始赋值。下一个'EB'-值301等
- 以'IN'开头的值应从400开始赋值。下一个'IN'-值401等
- 每个不以 'EB' 或 'IN' 开头的值都应从 500 开始指定数字。
- 我很乐意将它放在同一个 DataFrame 中。每个 EB 值及其在名称为 'C' 和 [=74= 的列中的编号,每个 'IN'-值及其名称在名称为 'E' 和 [= 的列中的编号77=] 以及列中的所有其他内容 '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。只要数组的长度。
我希望这个 post 没有变得太长。我很高兴能得到这里的每一个帮助。
这将为您提供您似乎想要的 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)
编辑:将 df_300
、df_400
和 df_500
的三个列表组合替换为 for
循环可能更优化,如下所示。如果您有大量的唯一值要分配代码,这种速度提升只会很明显,如果是这种情况,您可能希望代码为数万而不是数百:
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)
大家好,亲爱的 Whosebug 用户。我很想就一个让我头疼的问题得到一些指导。这就是我寻求帮助的部分,因为我的新手知识并不能帮助我解决这个问题。
简而言之:我有一组大量的数据,想知道如何给这些值一个唯一的数字来识别它们。但不是几次,只有一次。
我们有什么,想要什么:
- 2 列:A 和 B
- 大约 200 行。其中一些是重复的。我只会 post 一个子集。
- 值可以(但不是必须)同时出现在 A 列和 B 列中。如果出现,那么它可能会出现多次:可能只是一次或多次。
- 每个值只能指定一个数字一次。这很重要。
- 以'EB'开头的值应从300开始赋值。下一个'EB'-值301等
- 以'IN'开头的值应从400开始赋值。下一个'IN'-值401等
- 每个不以 'EB' 或 'IN' 开头的值都应从 500 开始指定数字。
- 我很乐意将它放在同一个 DataFrame 中。每个 EB 值及其在名称为 'C' 和 [=74= 的列中的编号,每个 'IN'-值及其名称在名称为 'E' 和 [= 的列中的编号77=] 以及列中的所有其他内容 '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。只要数组的长度。
我希望这个 post 没有变得太长。我很高兴能得到这里的每一个帮助。
这将为您提供您似乎想要的 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)
编辑:将 df_300
、df_400
和 df_500
的三个列表组合替换为 for
循环可能更优化,如下所示。如果您有大量的唯一值要分配代码,这种速度提升只会很明显,如果是这种情况,您可能希望代码为数万而不是数百:
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)