遍历df列列表并用字典中的值有效替换现有键python

时间:2020-05-31 12:14:04

标签: python pandas dataframe dictionary processing-efficiency

我有一个带有项目概率的字典。 我有一个500万行的df,看起来像这样:

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

由于我正在使用tqdm,所以我知道它要花多长时间(120小时),这太多了,而且显然效率不高。

关于我如何更有效地做到这一点的任何想法?

1 个答案:

答案 0 :(得分:1)

使用Series.transformitem_list中的每个项目转换为熊猫系列,并使用Series.map将该系列对应地映射到映射字典d,然后使用{{1} }删除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映射到item_list的速度):

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'])