pandas 如何将一个数据集的两列Map为另一个数据集的一列?

a11xaf1n  于 2023-03-28  发布在  其他
关注(0)|答案(2)|浏览(153)

我有两个数据集:

df1 = pd.DataFrame({'id1': 'AAA ABC ACD ADE AEE AFG'.split(),
                   'id2': 'BBB BBC BCD BDE BEE BFG'.split(),})

print(df1)

   id1  id2
0  AAA  BBB
1  ABC  BBC
2  ACD  BCD
3  ADE  BDE
4  AEE  BEE
5  AFG  BFG

-----------

df2 = pd.DataFrame({'student_id': 'ABC BBB AAA DEF AEE BEE'.split(),
                    'center': '11 22 33 44 55 66'.split()})

print(df2)

  student_id center
0        ABC     11
1        BBB     22
2        AAA     33
3        DEF     44
4        AEE     55
5        BEE     66

我需要将数据集1的id1id2列Map到数据集2的student_id列。然后只保留这些id1id2列,如果这两个列都存在于student_id列中。最后,分别从数据集2中获取它们的Map值作为单独的列。
我正在尝试下面的脚本,并为我的示例获得所需的输出:

map1 = df1.merge(df2, left_on='id1', right_on='student_id').drop(columns=['id2'])
map2 = df1.merge(df2, left_on='id2', right_on='student_id')
map1.merge(map2, on='id1')

然而,当数据集很大时,它既不能缩放也不能给出正确的输出。例如,map1长度为100,000行,map2长度为70,000行,连接两者后的最终长度接近100万。我尝试将id1设置为两个Map数据集的索引并连接它们,但它也不能缩放!

  • 所需输出 *
id1  id2 student_id1 center_1 student_id2 center_2
0  AAA  BBB         AAA       33         BBB       22 # Both AAA, BBB present from dataset 1, with respective values from dataset 2
1  AEE  BEE         AEE       55         BEE       66 # Both AEE, BEE present from dataset 1, with respective values from dataset 2

有什么更好的方法可以做到这一点?任何建议都将不胜感激。谢谢!

dgiusagp

dgiusagp1#

看起来您想像以前那样合并df1和df2,然后将df2合并到结果中,只是在不同的列(id2而不是id1)上,如下所示

map1 = df1.merge(df2, left_on='id1', right_on='student_id')
map2 = map1.merge(df2, left_on='id2', right_on='student_id', suffixes=['_1', '_2'])

这应该会产生正确的答案,并且只使用两个合并而不是三个合并来实现可伸缩性。

ryhaxcpt

ryhaxcpt2#

要将dataset 1的id 1和id 2列Map到dataset 2的student_id列,可以使用merge函数两次,每列一次,然后合并id 1列上的结果。下面是一个示例代码,可以有效地用于大型数据集:

# Merge id1 column
map1 = df1.merge(df2, left_on='id1', right_on='student_id', how='inner', suffixes=['', '_1'])

# Merge id2 column
map2 = df1.merge(df2, left_on='id2', right_on='student_id', how='inner', suffixes=['', '_2'])

# Merge both mappings on id1 column
result = map1.merge(map2, on='id1', how='inner')

# Keep only desired columns
result = result[['id1', 'id2', 'student_id', 'center', 'student_id_2', 'center_2']]

# Rename columns
result.columns = ['id1', 'id2', 'student_id1', 'center_1', 'student_id2', 'center_2']

# Keep only rows where both id1 and id2 are present in student_id column
result = result[(result['student_id1'].notnull()) & (result['student_id2'].notnull())]

# Reset index if needed
result = result.reset_index(drop=True)

下面是代码的作用:
1.首先,它根据id 1列合并df 1和df 2,并将结果保存为map 1。
1.然后,它根据id 2列合并df 1和df 2,并将结果保存为map 2。
1.最后,它根据id 1列合并map 1和map 2,并将结果保存为result。它只保留所需的列,并重命名它们以匹配所需的输出。
1.然后过滤结果,仅保留student_id列中同时存在id 1和id 2的行。
1.最后,如果需要,它会重置索引。请注意,我使用了'inner' join而不是默认的'outer' join来减少中间结果的大小,并且我使用了'suffixes'参数来区分两个student_id列。
希望这能有所帮助!

相关问题