代码之家  ›  专栏  ›  技术社区  ›  anat

迭代df列列表并用字典中的值替换现有的键

  •  1
  • anat  · 技术社区  · 5 年前

    我有一个关于概率项目的口述。

    user_id   item_list
     U1       [I1,I3,I4]
     U2       [I5,I4]
    

    还有一句话: {'I1': 0.1, 'I4': 0.4, ..}

    我试着去每一行,创建一个有概率的列表,比如:

    user_id   item_list     prob_list
     U1       [I1,I3,I4]    [0.1,0.4]
     U2       [I5,I4]       [0.4]
    

    这是我的代码:

    keys = list(prob_dict.keys())
    df['prob_list'] = df.progress_apply(lambda x: get_probability(prob_dict=prob_dict,
    keys=keys, item_list=x['item_list']),axis=1)
    
    def get_probability(prob_dict, keys, item_list):
    
    
        prob_list = []
        for item in item_list:
            if item  in keys:
               prob = prob_dict[item ]
               prob_list.append(prob)
    
        if len(prob_list)>=1:
            return prob_list
        else:
            return np.nan
    

    我有什么办法可以更有效地完成它吗?

    1 回复  |  直到 5 年前
        1
  •  1
  •   Shubham Sharma mkln    5 年前

    使用, Series.transform item_list 并相应地使用 Series.map 映射字典 d dropna NaN 价值观:

    d = {'I1': 0.1, 'I4': 0.4}
    
    df['prob_list'] = (
        df['item_list'].transform(lambda s: pd.Series(s).map(d).dropna().values)
    )
    

    更新 (使用 multiprocessing 项目清单 prob_list ):

    import multiprocessing as mp
    
    def map_prob(s):
        s = s[~s.isna()]
        return s.transform(
            lambda lst: [d[k] for k in lst if k in d] or np.nan)
    
    def parallel_map(item_list):
        splits = np.array_split(item_list, mp.cpu_count())
        pool = mp.Pool()
        prob_list = pd.concat(pool.map(map_prob, splits))
        pool.close()
        pool.join()
        return prob_list
    
    df['prob_list'] = parallel_map(df['item_list'])
    

    # print(df)
      uer_id     item_list   prob_list
    0     U1  [I1, I3, I4]  [0.1, 0.4]
    1     U2      [I5, I4]       [0.4]