繁体   English   中英

Pandas:加入/合并/合并两个数据帧

[英]Pandas : join/merge/concat two dataframes

问题:计算有多少人针对多个主题发表过论文

示例:

  1. Poo有两篇仅与Physics相关的论文,由于它只有一个主题,因此不考虑在内
  2. Amy的一篇论文有两(2)个主题( PhysicsEconomics ),所以应该计算在内
  3. 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:

  1. 您的第一个 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
  2. 您的第二个 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM