Python 嵌套循环中的动态列表
这是输入数据。正如您在下面的输入数据中所看到的,代码1和代码2实际上代表了与您在代码2中发现的“Kim S Tom”作为“比较”以及代码1中的“代理”相同的人。理想情况下,我希望所有的名称变化都使用唯一的代理名称,例如“Tom Kim” 输入数据: 这是我正在寻找的理想结果,这样我就可以在唯一的代理名“Tom Kim”下映射出相同人名的所有四种变体。我为代理使用哪个名称并不重要,只要它是唯一的标识符 我的期望: 这是我的代码,我不太确定如何达到理想的结果,我正在寻找如上所述。我真的很感激任何建议,因为我已经为此工作了很长一段时间了。。。谢谢Python 嵌套循环中的动态列表,python,pandas,Python,Pandas,这是输入数据。正如您在下面的输入数据中所看到的,代码1和代码2实际上代表了与您在代码2中发现的“Kim S Tom”作为“比较”以及代码1中的“代理”相同的人。理想情况下,我希望所有的名称变化都使用唯一的代理名称,例如“Tom Kim” 输入数据: 这是我正在寻找的理想结果,这样我就可以在唯一的代理名“Tom Kim”下映射出相同人名的所有四种变体。我为代理使用哪个名称并不重要,只要它是唯一的标识符 我的期望: 这是我的代码,我不太确定如何达到理想的结果,我正在寻找如上所述。我真的很感激任何
data = {'agent':['Tom Kim', 'Tom Kim', 'Kim S Tom', 'Kim S Tom','Catherine W','Catherine W'], 'compare':['Tom Kim','Kim S Tom','Tommy Kim','Kim Sun Tom','Wood Catherine','Catherine W']}
names = pd.DataFrame(data)
names.agent = pd.Categorical(names.agent)
names['code'] = names.agent.cat.codes
names_unique=names[['code']].drop_duplicates()
names_unique = names_unique.values.tolist()
mapping=pd.DataFrame(columns=['agent', 'compare'])
for f in list(names_unique):
agent_f=names[names['code'] == f]['compare']
agent_f=list(agent_f)
agent_name_f = names[names['code'] == f]['agent'][0]
agent_f_df=names[names['code'] == f][['agent','compare']]
mapping=mapping.append(agent_f_df)
names_unique.remove(f)
for s in list(names_unique):
agent_s = names[names['code'] == s]['agent'][0]
agent_s_df=names[names['code'] == s][['agent','compare']]
agent_name_s = names[names['code'] == s]['agent'][0]
if agent_s in agent_f:
agent_s_df['agent'] = agent_name_f
mapping=mapping.append(agent_s_df)
names_unique.remove(s)
else:
print(agent_name_f.strip().lower()+' AND '+agent_name_s.strip().lower()+' DID NOT MATCH')
我得到的结果:
如果我运行上面的代码,我会得到如下错误消息。如果没有嵌套循环,我可以无错误地运行此代码。这只适用于“f”循环的第一部分,忽略嵌套循环的“s”部分,然后运行
ValueError: list.remove(x): x not in list
我希望下面的代码会有帮助! 它会根据需要创建输出
import pandas as pd
data = {'agent':['Tom Kim', 'Tom Kim', 'Kim S Tom', 'Kim S Tom','Catherine W','Catherine W'], 'compare':['Tom Kim','Kim S Tom','Tommy Kim','Kim Sun Tom','Wood Catherine','Catherine W']}
names = pd.DataFrame(data)
names.agent = pd.Categorical(names.agent)
names['code'] = names.agent.cat.codes
# create unique names list, adding those names that are identical in both 'agent' and 'compare' columns
names_unique = []
for i in names.index:
if names['agent'][i] == names['compare'][i] and names['agent'][i] not in names_unique:
names_unique.append(names['agent'][i])
# create dictory to store output data, keys: unique names, values: list of all possible names
output_data = {}
for n in names_unique:
output_data[n] = [n]
# for each row of the input datafram
for i in names.index:
# for each key/values of the output data dictonary
for key, values in output_data.items():
# check if one between 'agent' or 'compare' is already among the possible names list of the unique name represented by the key selected by the for loop
# and check if the other column isn't already among the possible names
if names['agent'][i] in values and names['compare'][i] not in values:
# add the name to the possible names list
output_data[key].append(names['compare'][i])
if names['compare'][i] in values and names['agent'][i] not in values:
# add the name to the possible names list
output_data[key].append(names['agent'][i])
# organise your data to easily create your output dataframe
df_structure = {'agent': [], 'compare':[]}
for k in output_data.keys():
for v in output_data[k]:
df_structure['agent'].append(k)
df_structure['compare'].append(v)
# create output dataframe
output_df = pd.DataFrame(df_structure)
output_df
其功能的核心是用于迭代输入数据库所有行的for
循环
在每一行,它检查“agent”列中的名称或“compare”列中的名称是否已经在所有可能名称的列表中(字典输出数据的值
)
如果其中一个已在其中,则表示另一列中的名称是另一个可能的名称。因此,它会检查另一列中的名称是否也在可能的名称列表中。如果没有,则会添加
这样,在for
循环调用输入数据库的每一行之后,可能名称的列表都会更新
编辑:
解决问题作者在评论中提出的案例中唯一名称错误问题的替代代码:
import pandas as pd
data = {'agent':['Tom Kim', 'Tom Kim', 'Kim S Tom', 'Kim S Tom','Catherine W','Catherine W','Tom Kim'], 'compare':['Tom Kim','Kim S Tom','Tommy Kim','Kim S Tom','Wood Catherine','Catherine W','Kim Sum Tom']}
names = pd.DataFrame(data)
names.agent = pd.Categorical(names.agent)
names['code'] = names.agent.cat.codes
#create a list that will contain the groups of possible names
list_name_groups = []
#iterate over each row of the datafram "names"
for i in names.index:
# create variables to make the code more readable
agent = names['agent'][i]
compare = names['compare'][i]
# variable to check if the names in this row are in any group, starts with 0 (== not in any group)
is_in_any_group = 0
# iterate over each group of names already added to the list
for group in list_name_groups:
# if agent in the group, compare is added to the list of alternative names
if (agent in group) and (compare not in group):
group.append(compare)
is_in_any_group = 1 # an existing group is found
break
# if compare in the group, agent is added to the list of alternative names
if (compare in group) and (agent not in group):
group.append(agent)
is_in_any_group = 1 # an existing group is found
break
# in case both agent and compare are already in the group
if (compare in group) and (agent in group):
is_in_any_group = 1 # an existing group is found
break
# if neither agent nor compare are in the group
if is_in_any_group == 0:
if agent == compare: # avoid duplicates
list_name_groups.append([agent])
else: # the two names are different and both not in the group
list_name_groups.append([agent, compare])
# define the structure of the output dataframe
df_structure = {'agent': [], 'compare':[]}
for group in list_name_groups:
for name in group:
df_structure['agent'].append(group[0]) # the repeated name in the "agent" column is the first of the group
df_structure['compare'].append(name)
# create output dataframe
output_df = pd.DataFrame(df_structure)
output_df
这一个工作原理不同,它使用列表列表而不是字典
要选择将在输出数据帧的“代理”列中重复的名称,代码将选择可能的备选名称列表中的第一个。
我不确定你是否需要遵循一个特定的标准。。。在这种情况下,您可能需要修改代码的最后部分,其中定义了输出数据帧的结构 现在还不清楚你到底想达到什么目的。具体来说,你需要提供以下几点:1。这是我所期望的,2。这是我得到的结果,“f”不会递增,“name”在你的代码中永远不会改变大家好!谢谢你的反馈,我已经添加了更多关于我在寻找什么以及我收到了什么错误信息的描述。嗨,Giallo,这太棒了!非常感谢你!!我还有一个问题。如果原始数据是这样的呢?数据={'agent':['Tom Kim','Tom Kim','Kim S Tom','Catherine W','Catherine W'],'compare':['Tom Kim','Kim S Tom','Tommy Kim','Kim S Tom','Wood Catherine','Catherine W']}因此这将使代码中的“name_唯一”同时包含“Tom Kim”和“Kim S Tom而不仅仅是“Tom Kim”作为唯一的代理名称。你说得对!我已经编辑了我的答案来解决这个问题