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

打印熊猫中来自2个数据帧的所有映射数据

  •  1
  • anky  · 技术社区  · 6 年前

    我有一个数据帧:df1

      SAP_Name  SAP_Class  SAP_Sec
      Avi       5          Avi
      Rison     6          A 
      Slesh     7          B 
      San       8          C 
      Sud       7          B 
    

    df2型:

    Name_Fi Class std
    Avi     5     fgh
    Rison   6     Rij
    Slesh   7     jkh
    

    我正在尝试根据包含在两个数据帧的列中的值来获取头的映射。

    使用以下代码时:

    dfs1 = {col1: df1[col1].drop_duplicates() for col1 in df1.columns}
    set2 = {col2: set(df2[col2]) for col2 in df2.columns}
    d = {}
    for col2, v2 in set2.items():
        for col1, v1 in dfs1.items():
            cond = set(v2).issubset(v1)
            if cond:
               d[col2] = col1
    print(d)
    

    我有一个结果:

    {'Name_Fi': 'SAP_Name', 'Class': 'SAP_Class'}
    

    期望输出:

    {'Name_Fi': ['SAP_Name','SAP_Sec'], 'Class': 'SAP_Class'}
    

    基本上,只要df1中有匹配的值,就尝试打印每个匹配的列标题。有什么能帮忙的吗?

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

    我想需要 intersection 之间 set s,所以表演 dict comprehension 将字典的两个值转换为 设置 学生:

    from collections import defaultdict
    
    dfs1 = {col1: set(df1[col1].drop_duplicates()) for col1 in df1.columns}
    set2 = {col2: set(df2[col2]) for col2 in df2.columns}
    
    d = defaultdict(list)
    for col2, v2 in set2.items():
        for col1, v1 in dfs1.items():
            cond = v2.intersection(v1)
            if cond:
               d[col2].append(col1)
    print(d)
    defaultdict(<class 'list'>, {'Name_Fi': ['SAP_Name', 'SAP_Sec'], 'Class': ['SAP_Class']})
    
        2
  •  1
  •   jpp    6 年前

    你不是在找 issubset 这里,因为只有当一列中的值是另一列中的值的子集时,这才起作用,例如。 全部的 价值观 df2['Name_Fi'] 包含在 df1['SAP_Sec'] .. 相反,你可以使用 set.intersection ,或语法糖 & 检查是否有重叠。

    你可以把这个想法和 collections.defaultdict 提取您想要的结果:

    from collections import defaultdict
    
    d = defaultdict(list)
    for col2, v2 in set2.items():
        for col1, v1 in dfs1.items():
            cond = set(v2) & set(v1)
            if cond:
                d[col2].append(col1)
    
    print(d)
    
    defaultdict(<class 'list'>, {'Name_Fi': ['SAP_Name', 'SAP_Sec'],
                                 'Class': ['SAP_Class']})
    

    更有效的是,你可以计算 set 在嵌套循环中避免显式转换的理解中的对象:

    from collections import defaultdict
    
    dfs1 = {col1: set(df1[col1]) for col1 in df1}
    set2 = {col2: set(df2[col2]) for col2 in df2}
    
    d = defaultdict(list)
    
    for col2, v2 in set2.items():
        for col1, v1 in dfs1.items():
            if v2 & v1:
                d[col2].append(col1)
    
    print(d)
    

    对于较大的数组,可以使用 pd.Series.unique + any 使用更有效的生成器表达式:

    import pandas as pd
    import numpy as np
    
    np.random.seed(0)
    A = pd.Series(np.random.randint(0, 1000, 10000)).unique()
    B = pd.Series(np.random.randint(0, 100000, 10000)).unique()
    
    %timeit np.in1d(B, A).any()     # 1.1 ms per loop
    %timeit set(A) & set(B)         # 1.46 ms per loop
    %timeit any(i in B for i in A)  # 102 µs per loop