使用数据帧减去字典中列表的值

时间:2018-03-06 12:10:27

标签: python list pandas dictionary

下面有一个数据框,用户购买的产品。

DataSet:

user    age maritalstatus   product
A   Young   married 111
B   young   married 222
C   young   Single  111
D   old single  222
E   old married 111
F   teen    married 222
G   teen    married 555
H   adult   single  444
I   adult   single  333

词典:

{A:[111,222], B:[111,222], C:[111], D:[222], G:[222,555], X:[222,444] } 

预期产出:

{A:[222], B:[111], C:[], D:[], G:[222], X:[222,444] }

字典应查看数据框并删除用户已购买的产品。

3 个答案:

答案 0 :(得分:4)

你可以使用词典理解:

{k:[e for e in v if e not in df.loc[df.user.eq(k), 'product'].tolist()] for k,v in d.items()}
Out[292]: {'A': [222], 'B': [111], 'C': [], 'D': [], 'G': [222], 'X': [222, 444]}

一个稍微详细的解决方案,以便于理解:

首先构建用户产品词典:

user_prod = df.groupby('user')['product'].apply(list).to_dict()
{'A': [111],
 'B': [222],
 'C': [111],
 'D': [222],
 'E': [111],
 'F': [222],
 'G': [555],
 'H': [444],
 'I': [333]}

然后,使用dict理解来删除user_prod dict中的元素。

{k:[e for e in v if e not in user_prod.get(k,[])] for k,v in d.items()}
Out[319]: {'A': [222], 'B': [111], 'C': [], 'D': [], 'G': [222], 'X': [222, 444]}

使用user_prod.get是必要的,因为用户可能不存在,而.get将通过返回空列表来避免异常。

答案 1 :(得分:2)

这是实现逻辑的一种直观方式。您可以通过集合和理解进行优化,但对于合理大小的数据集,下面的方法应该足够了。

products = df.groupby('user')['product'].apply(list)

d = {'A':[111,222], 'B':[111,222], 'C':[111], 'D':[222], 'G':[222,555], 'X':[222,444] } 

for k, v in d.items():
    p = products.get(k)
    if p:
        for i in p:
            d[k].remove(i)

# {'A': [222], 'B': [111], 'C': [], 'D': [], 'G': [222], 'X': [222, 444]}

答案 2 :(得分:-1)

   product  user
0        1    10
1        2    11
2        1    12
3        1    13
4        2    14

new_purchase = frame.set_index('user')['product'].to_dict()
{10: 1, 11: 2, 12: 1, 13: 1, 14: 2}

{10: [2, 1], 11: [2], 12: [], 13: [22], 14: [1]}
result = {}
        for k, v in prev_purchase.items():
            result[k] = [item for item in v if item not in [new_purchase[k]]]
  

{10:[2],11:[],12:[],13:[22],14:[1]}