[英]Pandas : join/merge/concat two dataframes
问题:计算有多少人针对多个主题发表过论文
示例:
Poo
有两篇仅与Physics
相关的论文,由于它只有一个主题,因此不考虑在内Amy
的一篇论文有两(2)个主题( Physics
、 Economics
),所以应该计算在内Baa
有两篇论文,每篇论文都有不同的主题,所以应该计算在内示例数据框:
| | id | name | has_published_papers |
|---|-----|------|-----------------------------------------|
| 0 | 100 | Amy | pp3524172 |
| 1 | 101 | Bla | pp0120888,pp0343660,pp0151738,pp0120631 |
| 2 | 102 | Foo | pp0134084,pp1262416,pp0120082,pp0117571 |
| 3 | 103 | Boo | pp0274558,pp0108872,pp1796960,pp0117509 |
| 4 | 104 | Soo | pp0120338,pp0993846,pp1375666,pp0407887 |
| 5 | 111 | Poo | pp0152095,pp1234567 |
| 6 | 112 | Baa | pp0237474,pp0152095 |
| | paper_id | name | topics |
|----|-----------|-------------|--------------------|
| 30 | pp3524172 | research A | Physics, Economics |
| 40 | pp0189076 | research B | Math, Physics |
| 55 | pp0237474 | research C | Education |
| 68 | pp2729488 | research D | Physics, Math |
| 79 | pp0152095 | research Z | Physics |
| 99 | pp1234567 | research X | Physics |
编辑所需的 output 是integer
代表发表过多个主题的论文的人数
您需要几个步骤来合并这些数据集。
您要做的第一件事是将has_published_papers
列拆分并扩展为多个列:
authors_df = pd.DataFrame({
'id': [100, 101],
'name': ['Amy', 'Bla'],
'has_published_papers': ['pp3524172', 'pp0120888,pp0343660,pp0151738,pp0120631']
})
authors_df.has_published_papers.str.split(',', expand=True)
这将是 output
0 1 2 3
0 pp3524172 None None None
1 pp0120888 pp0343660 pp0151738 pp0120631
然后你可以将它连接到你原来的 dataframe 并融化它:
authors_papers_df = (
pd.concat([
authors_df.drop(columns=['has_published_papers']),
authors_df.has_published_papers.str.split(',', expand=True)
], axis=1)
.melt(['id', 'name'], value_name='paper_id')
.dropna(subset=['paper_id']))
这将 output 一个不错的 dataframe 准备好合并:
id name variable paper_id
0 100 Amy 0 pp3524172
1 101 Bla 0 pp0120888
3 101 Bla 1 pp0343660
5 101 Bla 2 pp0151738
7 101 Bla 3 pp0120631
您可以执行完全相同的拆分/扩展/融化管道来创建论文主题 dataframe。
papers_topics_df = (
pd.concat([
papers_df.drop(columns=['topics']),
papers_df.topics.str.split(', ', expand=True)
], axis=1)
.melt(['paper_id', 'name'], value_name='topic')
.dropna(subset=['topic'])
)
然后你可以在paper_id
上合并。
authors_papers_topics_df = authors_papers_df.merge(papers_topics_df, on='paper_id')
现在你有一个 dataframe 相关主题、论文和作者。
要计算每个作者的唯一主题,您可以使用:
authors_papers_topics_df.groupby('id')['topics'].nunique()
看到你的编辑。 要获取拥有多个主题的作者数量,请使用:
np.sum(authors_papers_topics_df.groupby('id')['topics'].nunique() > 1)
首先转换两个 DataFrame:
您的第一个 DataFrame ( df ) 到 DataFrame ,每篇论文都有单独的行,论文 ID 作为索引:
paper = df.set_index('name').has_published_papers.str.split(',')\.explode().reset_index(name='id').set_index('id')
结果是:
name id pp3524172 Amy pp0120888 Bla pp0343660 Bla pp0151738 Bla pp0120631 Bla pp0134084 Foo pp1262416 Foo pp0120082 Foo pp0117571 Foo pp0274558 Boo pp0108872 Boo pp1796960 Boo pp0117509 Boo pp0120338 Soo pp0993846 Soo pp1375666 Soo pp0407887 Soo pp0152095 Poo pp1234567 Poo pp0237474 Baa pp0152095 Baa
您的第二个 DataFrame ( df2 ) 到一个系列,将每个主题行划分为单独的元素,并再次将论文 ID 作为索引:
topic = df2.set_index('paper_id').topics.str.split(', ').explode()
结果是:
paper_id pp3524172 Physics pp3524172 Economics pp0189076 Math pp0189076 Physics pp0237474 Education pp2729488 Physics pp2729488 Math pp0152095 Physics pp1234567 Physics Name: topics, dtype: object
然后:
执行此操作的代码是:
result = paper.join(topic).dropna().reset_index(drop=True)\
.drop_duplicates().groupby('name').count().reset_index()
得到:
name topics
0 Amy 2
1 Baa 2
2 Poo 1
要获得真正的最终结果,请检索主题 > 1的行并仅获取名称列:
result.query('topics > 1').name
最终结果是:
0 Amy
1 Baa
Name: name, dtype: object
或者,如果您想获得普通的Pythonic列表(而不是Series ),请将.tolist()
添加到上述指令中,这次将获得:
['Amy', 'Baa']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.