【发布时间】:2021-06-29 17:16:28
【问题描述】:
我的数据包含人名和他们居住的城市列表。我想按照以下条件将它们组合在一起:
-
-
first_name和last_name相同
-
-
- 或(如果 1. 不成立)他们的
last_name是相同的,并且他们至少住在一个相同的city中。
- 或(如果 1. 不成立)他们的
结果应该是一个新列,指示每个人所属的组 ID。
DataFrame df 如下所示:
>>> df
person_id last_name first_name cities
0 112 Dorsey Nancy [Moscow, New York]
1 113 Harper Max [Munich, Paris, Shanghai]
2 114 Mueller Max [New York, Los Angeles]
3 115 Dorsey Nancy [New York, Miami]
4 116 Harper Maxwell [Munich, Miami]
新的数据框df_id 应该如下所示。 id 的顺序无关紧要(即,哪个组得到 id=1),但只有满足条件 1 或 2 的观察才能得到相同的 id。
>>> df_id
person_id last_name first_name cities id
0 112 Dorsey Nancy [Moscow, New York] 1
1 113 Harper Max [Munich, Paris, Shanghai] 2
2 114 Mueller Max [New York, Los Angeles] 3
3 115 Dorsey Nancy [New York, Miami] 1
4 116 Harper Maxwell [Munich, Miami] 2
我当前的代码:
df= df.reset_index(drop=True)
#explode lists to rows
df_exploded = df.explode('cities')
# define id_counter and dictionary to person_id to id
id_counter = 1
id_matched = dict()
# define id function
def match_id(df):
global id_counter
# check if person_id already matched
if df['person_id'] not in id_matched.keys():
# get all persons with similar names (condition 1)
select = df_expanded[(df_expanded['first_name']==df['first_name']) & df_expanded['last_name']==df['last_name'])]
# get all persons with same last_name and city (condition 2)
if select.empty:
select_2 = df_expanded[(df_expanded['last_name']==df['last_name']) & (df_expanded['cities'] in df['cities'])]
# create new id for this specific person
if select_2.empty:
id_matched[df['person_id']] = id_counter
# create new id for group of person and record in dictionary
else:
select_list = select_2.unique().tolist()
select_list.append(df['person_id'])
for i in select_list:
id_matched[i] = id_counter
# create new id for group of person and record in dictionary
else:
select_list = select.unique().tolist()
select_list.append(df['person_id'])
for i in select_list:
id_matched[i] = id_counter
# set next id
id_counter += 1
# run function
df = df.progress_apply(match_id, axis=1)
# convert dict to DataFrame
df_id_matched = pd.DataFrame.from_dict(id_matched, orient='index', columns['id'])
.rename_axis('person_id').reset_index()
# merge back together with df to create df_id
有没有人有更有效的方法来执行这项任务?数据集很大,需要几天时间...
提前致谢!
【问题讨论】:
-
能否请您解释一下行索引 1 和 4 是如何变得相同的?
-
根据条件 2,它们都有相同的
last_name和相同的cities=='Munich'
标签: python pandas pandas-groupby