【问题标题】:Pandas: Add a new column in a data frame based on a value in another data framePandas:根据另一个数据框中的值在数据框中添加新列
【发布时间】:2016-11-15 06:17:23
【问题描述】:

我有两个数据框,其中一个包含 userId 和性别,另一个数据框包含这些用户的在线活动。

第一个数据帧(df1)

userId, gender
001, F
002, M
003, F
004, M
005, M
006, M

第二个数据框(df2)

userId, itemClicked, ItemBought, date
001, 123182, 123212, 02/02/2016
003, 234256, 123182, 05/02/2016
005, 986834, 234256, 04/19/2016
004, 787663, 787663, 05/12/2016
020, 465738, 465738, 03/20/2016
004, 787223, 787663, 07/12/2016

我想通过根据 userId 查找第一个数据框来将性别列添加到第二个数据框。 df2 每个用户可能有多行,因为它是一个点击数据,其中同一个用户可能点击了多个项目。

这在 MySql 中很容易做到,但我正在尝试在 pandas 中做到这一点。

for index, row in df2.iterrows():
    user_id = row['userId']
    if user_id in df1['userId']:
        t = df1.loc[df1['userId'] == user_id]
        pdb.set_trace()

这是完成这样一项任务的熊猫方式吗?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:
    print (df1)
       userId gender
    0       1      F
    1       2      M
    2       3      F
    3       4      M
    4       5      M
    5       6      M
    
    print (df2)
       userId  itemClicked  ItemBought        date
    0       1       123182      123212  02/02/2016
    1       3       234256      123182  05/02/2016
    2       5       986834      234256  04/19/2016
    3       4       787663      787663  05/12/2016
    4      20       465738      465738  03/20/2016
    5       4       787223      787663  07/12/2016
    

    你可以使用map:

    df2['gender'] = df2.userId.map(df1.set_index('userId')['gender'].to_dict())
    
    print (df2)
       userId  itemClicked  ItemBought        date gender
    0       1       123182      123212  02/02/2016      F
    1       3       234256      123182  05/02/2016      F
    2       5       986834      234256  04/19/2016      M
    3       4       787663      787663  05/12/2016      M
    4      20       465738      465738  03/20/2016    NaN
    5       4       787223      787663  07/12/2016      M
    

    另一个使用merge 和左连接的解决方案,如果两个DataFrame 中只有列gender 相同,则可以省略参数on:

    df = pd.merge(df2, df1, how='left')
    
    print (df)
       userId  itemClicked  ItemBought        date gender
    0       1       123182      123212  02/02/2016      F
    1       3       234256      123182  05/02/2016      F
    2       5       986834      234256  04/19/2016      M
    3       4       787663      787663  05/12/2016      M
    4      20       465738      465738  03/20/2016    NaN
    5       4       787223      787663  07/12/2016      M
    

    时间安排:

    #len(df2) = 600k
    df2 = pd.concat([df2]*100000).reset_index(drop=True)
    
    def f(df1,df2):
        df2['gender'] = df2.userId.map(df1.set_index('userId')['gender'].to_dict())
        return df2
    
    
    In [43]: %timeit f(df1,df2)
    10 loops, best of 3: 34.2 ms per loop
    
    In [44]: %timeit (pd.merge(df2, df1, how='left'))
    10 loops, best of 3: 102 ms per loop
    

    【讨论】:

    • 在处理大型数据帧 1000 万条记录时,这是一种好方法吗?
    • df2 可能不止一次拥有同一个用户,因为它是点击/交易数据。合并可能有问题吧。
    • 我加计时,map解决方案最快。
    • 看起来无法合并,因为第二个数据框没有性别列。是否可以做这样的事情 df2['gender'] = NULL,然后进行合并
    • 我认为没有问题,因为它与(pd.merge(df2, df1, how='left', on='userId')) 相同 - 它在userId 列上左连接
    【解决方案2】:

    如果 user_id 是您可以使用的索引:

    df2.join(df1)
    

    【讨论】:

    • 第二个数据框每个同一用户有多个记录,因此很难为该数据框创建索引。
    【解决方案3】:

    你可以试试这个:

    for index, row in df1.iterrows():
       for ind,r in df2.iterrows():
          if r['userId']==row['userId']:
             df2.set_value(ind,'Gender',row['gender'])
             break
    

    【讨论】:

      猜你喜欢
      • 2020-04-27
      • 2018-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-23
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多