Python pandas:使用多个列条件将数据框的索引值设置为另一个数据框的列

时间:2019-06-19 20:05:07

标签: python python-3.x pandas

我有两个数据帧:data_dfgeo_dimension_df

我想获取索引geo_dimension_df的索引,将其重命名为id,并使其在data_df上的列称为geo_id

我将把这两个数据帧作为表插入数据库,并且id列将是它们的主键,而geo_id是一个外键,它将data_df链接到geo_dimension_df

可以看出,cbsaname的值会随着时间变化。 (加利福尼亚州尤巴市->加利福尼亚州马里斯维尔尤巴市)。因此,geo_dimension_dfcbsaname的唯一组合。

我需要比较两个数据帧上的cbsaname值,然后在将集合geo_dimension_df.id匹配为data_df.geo_id值时进行比较。

我尝试使用merge了一段时间,但感到困惑,所以现在我尝试使用apply并像跨多个列值的Excel vlookup一样查看它,但是没有运气。以下是我的尝试,但这有点胡乱...

data_df['geo_id'] = data_df[['cbsa', 'name']]
                        .apply(
                        lambda x, y: 
                        geo_dimension_df
                            .index[geo_dimension_df[['cbsa', 'name]]
                            .to_list()
                        == [x,y])

下面是两个原始数据帧,后跟所需的结果。谢谢。

geo_dimension_df:

       cbsa                               name
id                           
  1   10180                        Abilene, TX
  2   10420                          Akron, OH
  3   10500                         Albany, GA
  4   10540                         Albany, OR
  5   10540                 Albany-Lebanon, OR
                     ...
519   49620                   York-Hanover, PA
520   49660  Youngstown-Warren-Boardman, OH-PA
521   49700                      Yuba City, CA
522   49700           Yuba City-Marysville, CA
523   49740                           Yuma, AZ

data_df:

             cbsa         name  month  year units_total
        id                                             
        1   10180  Abilene, TX      1  2004          22
        2   10180  Abilene, TX      2  2004          12
        3   10180  Abilene, TX      3  2004          44
        4   10180  Abilene, TX      4  2004          32
        5   10180  Abilene, TX      5  2004          21
                                 ...
    67145   49740  Yuma, AZ        12  2018          68
    67146   49740  Yuma, AZ         1  2019          86
    67147   49740  Yuma, AZ         2  2019          99
    67148   49740  Yuma, AZ         3  2019          99
    67149   49740  Yuma, AZ         4  2019          94

所需结果:
data_df(添加了geo_id外键列):

             cbsa         name  month  year units_total geo_id
        id                                             
        1   10180  Abilene, TX      1  2004          22      1
        2   10180  Abilene, TX      2  2004          12      1
        3   10180  Abilene, TX      3  2004          44      1
        4   10180  Abilene, TX      4  2004          32      1
        5   10180  Abilene, TX      5  2004          21      1
                                 ...
    67145   49740  Yuma, AZ        12  2018          68    523
    67146   49740  Yuma, AZ         1  2019          86    523
    67147   49740  Yuma, AZ         2  2019          99    523
    67148   49740  Yuma, AZ         3  2019          99    523
    67149   49740  Yuma, AZ         4  2019          94    523

注意:此后,我将从cbsa中删除namedata_df,以防万一有人好奇我为什么要复制数据。

1 个答案:

答案 0 :(得分:1)

首先,由于索引不是正确的列,因此将其设置为列,以便可以在以后的merge中使用它:

geo_dimension_df['geo_id'] = geo_dimension_df.index

接下来,加入data_dfgeo_dimension_df

data_df = pd.merge(data_df, 
                   geo_dimension_df['cbsa', 'name', 'geo_id'],
                   on=['cbsa', 'name'],
                   how='left')  

最后,首先将添加到geo_dimension_df的列删除:

geo_dimension_df.drop('geo_id', axis=1, inplace=True)

完成此操作后,geo_dimension_df的索引列id现在将显示在data_df的列geo_id下:

data_df:

         cbsa         name  month  year units_total geo_id
    id                                             
    1   10180  Abilene, TX      1  2004          22      1
    2   10180  Abilene, TX      2  2004          12      1
    3   10180  Abilene, TX      3  2004          44      1
    4   10180  Abilene, TX      4  2004          32      1
    5   10180  Abilene, TX      5  2004          21      1
                             ...
67145   49740  Yuma, AZ        12  2018          68    523
67146   49740  Yuma, AZ         1  2019          86    523
67147   49740  Yuma, AZ         2  2019          99    523
67148   49740  Yuma, AZ         3  2019          99    523
67149   49740  Yuma, AZ         4  2019          94    523