【问题标题】:Setting the index after merging with pandas?与熊猫合并后设置索引?
【发布时间】:2020-04-05 04:45:00
【问题描述】:

执行以下合并

import pandas as pd
s = pd.Series(range(5, 10), index=range(10, 15), name='score')
df = pd.DataFrame({'id': (11, 13), 'value': ('a', 'b')})
pd.merge(s, df, 'left', left_index=True, right_on='id')

这个数据框的结果:

     score  id value
NaN      5  10   NaN
0.0      6  11     a
NaN      7  12   NaN
1.0      8  13     b
NaN      9  14   NaN

为什么即使我指定了左合并和left_index=True,Pandas 仍将右侧数据帧中的索引而不是左侧系列中的索引作为结果的索引? documentation

left:仅使用左帧中的键

我对它的解释与我实际得到的结果不同。我期望的是以下数据框。

    score  id value
10      5  10   NaN
11      6  11     a
12      7  12   NaN
13      8  13     b
14      9  14   NaN

我正在使用 Python 3.7.5 和 Pandas 0.25.3。

【问题讨论】:

    标签: python pandas dataframe merge series


    【解决方案1】:

    由于我不需要 id 列和索引中的重复信息,因此我结合了 cs95 和 oppressionslayer 的答案,并执行了以下操作:

    pd.merge(s, df, 'left', left_index=True, right_on='id').set_index('id')
    

    这会导致这个数据框:

        score value
    id             
    10      5   NaN
    11      6     a
    12      7   NaN
    13      8     b
    14      9   NaN
    

    由于这与我最初要求的不同,我将 cs95 的答案作为接受的答案,但我认为这个用例也需要记录在案。

    【讨论】:

      【解决方案2】:

      你可以用 reset_index 做到这一点:

      df = pd.merge(s,df, 'left', left_index=True, right_on='id').reset_index(drop=True).set_index('id').rename_axis(index=None)
      df.insert(1, 'id', df.index)
      
          score  id value
      10      5  10   NaN
      11      6  11     a
      12      7  12   NaN
      13      8  13     b
      14      9  14   NaN
      

      【讨论】:

      • 感谢您的回答,但索引并不总是等于 range(len(s))。我应该更清楚这一点。请参阅我的问题的编辑。
      • 我已更新以进行更改,因此答案是正确的
      【解决方案3】:

      发生了什么:

      1. 输出索引是索引/列合并键[0, 1]的交集。
      2. 缺失的键被替换为 NaN
      3. NaN 导致索引类型向上转换为 float

      要设置索引,只需分配给它:

      s2 = pd.merge(s, df, how='left', left_index=True, right_on='id')
      s2.index = s.index
      
          score  id value
      10      5  10   NaN
      11      6  11     a
      12      7  12   NaN
      13      8  13     b
      14      9  14   NaN
      

      你也可以在s上合并(只是因为我不喜欢直接调用pd.merge):

      (s.to_frame()
        .merge(df, how='left', left_index=True, right_on='id')
        .set_axis(s.index, axis=0, inplace=False))
      
          score  id value
      10      5  10   NaN
      11      6  11     a
      12      7  12   NaN
      13      8  13     b
      14      9  14   NaN
      

      【讨论】:

      • 感谢您的回答,但它并不真正适合我的用例。我想保留系列中的索引,它并不总是等于 range(len(s))。我编辑了我的问题以澄清这一点。
      • @Hendrikto 刚才应该这么说,你可以在合并后设置索引;查看我的编辑。
      猜你喜欢
      • 2021-09-01
      • 2021-07-31
      • 2018-06-17
      • 1970-01-01
      • 2018-02-02
      • 1970-01-01
      • 2016-08-01
      • 2012-12-18
      • 2017-05-07
      相关资源
      最近更新 更多