代码之家  ›  专栏  ›  技术社区  ›  Jonas Palačionis

基于另一个数据帧值对值进行排序

  •  0
  • Jonas Palačionis  · 技术社区  · 4 年前

    我有一个 df_1 这样地:

    A                      
    
    apple, iphone, android
    facebook, apple
    macbook, laptop
    firestick, hulu, netflix
    android, laptop
    laptop
    

    df_2 这样地:

    A           B
    
    apple       1
    macbook     2
    facebook    3
    firestick   4
    hulu        5
    netflix     6
    android     7
    laptop      8
    

    A 列中具有最低值的 B 数据框2 像这样:

    A                               B_new
    
    apple, iphone, android          apple
    facebook, apple                 apple
    macbook, laptop                 macbook
    hulu, netflix, firestick        firesick
    laptop, android                 android                 
    laptop                          laptop
    

    我想我可以对每个值进行排序 数据框1 基于 B类 在里面 数据框2 . 或者创建一个函数 A 数据框1 返回 str B类 . 但由于数据很大,我假设 apply 效率不高。有整洁的房间吗 这样做的方法?

    1 回复  |  直到 4 年前
        1
  •  2
  •   jezrael    4 年前

    您可以创建字典和匹配值(如果存在),然后获取最大值(否则缺少值):

    d = df_2.set_index('A')['B'].to_dict()
    
    def f(x):
        d1 = {y:d[y] for y in x.split(', ') if y in d}
        return min(d1, key=d1.get)  if len(d1) > 1 else np.nan
    

    import operator
    
    def f(x):
        d1 = {y:d[y] for y in x.split(', ') if y in d}
        return min(d1.items(), key=operator.itemgetter(1))[0] if len(d1) > 1 else np.nan
    

    df_1['new'] = df_1['A'].apply(f)
    print (df_1)
                              A        new
    0    apple, iphone, android      apple
    1           facebook, apple      apple
    2           macbook, laptop    macbook
    3  firestick, hulu, netflix  firestick
    4           android, laptop    android
    5                    laptop     laptop
    
        2
  •  1
  •   sammywemmy    4 年前

    @jezrael的解决方案更干净,而且应该更快,因为我们处理的是字符串;下面的解决方案是另一种选择:

    values = [[value.strip() for value in entry.split(",")] 
              for entry in df1.A.__iter__()]
    values
    
    [['apple', 'iphone', 'android'],
     ['facebook', 'apple'],
     ['macbook', 'laptop'],
     ['firestick', 'hulu', 'netflix'],
     ['android', 'laptop'],
     ['laptop']]
    

    获取最小值,在这种情况下,它将是第一个真值:

    values = [df2.loc[df2.A.isin(value), "B"].idxmin() 
              for value in values]
    values
    [0, 0, 1, 3, 6, 7]
    

    df1.loc[:, 'B_new'] = df2.iloc[values, 0]
    
    
           A                           B_new
    0   apple, iphone, android         apple
    1   facebook, apple                apple
    2   macbook, laptop               macbook
    3   firestick, hulu, netflix    firestick
    4   android, laptop              android
    5   laptop                        laptop
    
        3
  •  0
  •   Whole Brain    4 年前

    也不是最快的,但我喜欢另一种思考方式。

    ab_dict = df_2.set_index("A")["B"].to_dict()
    df_1["B"] = df_1["A"].str.get_dummies(", ")
            .apply(lambda c: c.replace(0, np.nan)*ab_dict.get(c.name, np.nan))
            .idxmin(axis=1)