根据特定条件在熊猫的两个表中比较两列

时间:2020-03-17 09:16:29

标签: pandas pandas-groupby

我有两个数据框,如下所示。

用户表:每个用户参加的课程和模块的详细信息。

user_id     courses.  Num_of_course     attended_modules              Total_Modules
1           [A]       1                 {A:[1,2,3,4,5,6]}             6
2           [A,B,C]   3                 {A:[8], B:[5], C:[6]}         3 
3           [A,B]     2                 {A:[2,3,9], B:[10]}           4
4           [A]       1                 {A:[3]}                       1
5           [B]       1                 {B:[5]}                       1
6           [A]       1                 {A:[3]}                       1
7           [B]       1                 {B:[5]}                       1
8           [A]       1                 {A:[4]}                       1

课程表:有关课程以及该课程中所有模块和流行模块的详细信息。

course_id         modules                 #users        Popular_modules
A                 [1,2,3,4,5,6,8,9]       5             [3,2]
B                 [5,8]                   4             [5]
C                 [6,10]                  2             []

从上表中比较两列有人参与的模块和模块,并为参加课程的每个用户建议无人参与的模块。

  1. 如果用户尚未参加该课程,则建议在该课程中使用该流行模块。
  2. 按照课程表中的顺序,建议正在进行的课程中的无人值守模块。
  3. 如果该课程有3个模块,则建议他参加的每个课程的所有用户使用3个模块。

预期输出:

user_id         courses.       Recommended_modules              
    1           [A,B]          {A:[8,9]}    
    2           [A,B,C]        {A:[3,2,1], B:[8], C:[10]}          
    3           [A,B]          {A:[1,4,5], B:[5,8]}           
    4           [A]            {A:[2,1,4]}                       
    5           [B]            {B:[8]}                       
    6           [A]            {A:[2,1,4]}                       
    7           [B]            {B:[8]}                       
    8           [A]            {A:[3,2,1]}

编辑:

添加了user_id = 9(最后一行)

user_id     courses.  Num_of_course     attended_modules              Total_Modules
1           [A]       2                 {A:[1,2,3,4,5,6]}             6
2           [A,B,C]   3                 {A:[8], B:[5], C:[6]}         3 
3           [A,B]     2                 {A:[2,3,9], B:[10]}           4
4           [A]       1                 {A:[3]}                       1
5           [B]       1                 {B:[5]}                       1
6           [A]       1                 {A:[3]}                       1
7           [B]       1                 {B:[5]}                       1
8           [A]       1                 {A:[4]}                       1
9           [A]       1                 {A:[1,2,3,4,5,6,8,9], B:[5]}  8 

以上代码的输出为

     user_id        courses.       Recommended_modules              
        1           [A]            {A:[8,9]}    
        2           [A,B,C]        {A:[3,2,1], B:[8], C:[10]}          
        3           [A,B]          {A:[1,4,5], B:[5,8]}           
        4           [A]            {A:[2,1,4]}                       
        5           [B]            {B:[8]}                       
        6           [A]            {A:[2,1,4]}                       
        7           [B]            {B:[8]}                       
        8           [A]            {A:[3,2,1]}
        9           [A,B]          {A:[], B:[8]} 

在“用户ID = 9”的“推荐模块”中,课程A的列表为空

即{A:[],B:[8]}预期为{B:[8]}

预期输出:

         user_id        courses.       Recommended_modules              
            1           [A]            {A:[8,9]}    
            2           [A,B,C]        {A:[3,2,1], B:[8], C:[10]}          
            3           [A,B]          {A:[1,4,5], B:[5,8]}           
            4           [A]            {A:[2,1,4]}                       
            5           [B]            {B:[8]}                       
            6           [A]            {A:[2,1,4]}                       
            7           [B]            {B:[8]}                       
            8           [A]            {A:[3,2,1]}
            9           [A,B]          {B:[8]}

1 个答案:

答案 0 :(得分:1)

使用带有不同字典的cunstom函数,lastm用if-else创建新的字典,用于输入中的空列表也是空列表:

df2 = df2.set_index('course_id')
mo = df2['modules'].to_dict()
#print (mo)

pop = df2['Popular_modules'].to_dict()
#print (pop)

def f(x):
    out = {}
    for k, v in x.items():
        dif = [i for i in mo[k] if i not in v]
        a = [i for i in pop[k] if i in dif]
        b = [i for i in dif if i not in pop[k]]
        c = a + b
        out[k] = c[:3]    
    return out

df1['Recommended_modules'] = df1['attended_modules'].apply(f)
df1 = df1[['user_id','courses.','Recommended_modules']]
print (df1)
   user_id courses.           Recommended_modules
0        1    [A,B]           {'A': [8, 9]}
1        2  [A,B,C]           {'A': [3, 2, 1], 'B': [8], 'C': [10]}
2        3    [A,B]           {'A': [1, 4, 5], 'B': [5, 8]}
3        4      [A]           {'A': [2, 1, 4]}
4        5      [B]           {'B': [8]}
5        6      [A]           {'A': [2, 1, 4]}
6        7      [B]           {'B': [8]}
7        8      [A]           {'A': [3, 2, 1]}

编辑:如果attended_modules输入栏中的字典中有空列表,并且需要在输出函数中将其删除,则更改:

def f(x):
    out = {}
    for k, v in x.items():
        dif = [i for i in mo[k] if i not in v]
        a = [i for i in pop[k] if i in dif]
        b = [i for i in dif if i not in pop[k]]
        c = a + b
        if len(v) > 0:
            out[k] = c[:3]    
    return out