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

如何合并两个基于数字的列标题不断增加的数据帧?

  •  0
  • userj  · 技术社区  · 3 年前

    我现在有两个数据帧,看起来有点像这样,但要大得多。数据帧1:

    Q1 问题2 第三季度 第四季度 问题5 问题6
    A. B C D E F

    数据帧2:

    Q1 问题2 第三季度 第四季度
    A. B D F

    因此,dataframe 2与dataframe 1相同,但它缺少dataframe 1中的Q3和Q5。数据帧2中的Q3相当于数据帧1中的Q4,数据帧2中的Q4与数据帧1中的Q6相同。我想把这两个表合并在一起,看起来像这样:

    Q1 问题2 第三季度 第四季度 问题5 问题6
    A. B C D E F
    A. B 无效的 D 无效的 F

    实际上,我的表比本例中显示的要大得多,第二个表中的列要多,缺少的问题也要多。所以我只是想知道是否有人能做到这一点,这样我就不必手动重命名和填充所有列。非常感谢。

    1 回复  |  直到 3 年前
        1
  •  0
  •   osbm    3 年前

    我认为你描述的行动是 pd.concat 正如@sammywemmy所说。

    import pandas as pd
    
    df1 = pd.DataFrame({'Q1': ['a'], 'Q2': ['b'], 'Q3': ['c'], 'Q4': ['d'], 'Q5': ['e'], 'Q6': ['f']})
    df2 = pd.DataFrame({'Q1': ['a'], 'Q2': ['b'], 'Q3': ['d'], 'Q4': ['f']})
    
    print(pd.concat([df1, df2]))
    

    输出:

      Q1 Q2 Q3 Q4   Q5   Q6
    0  a  b  c  d    e    f
    0  a  b  d  f  NaN  NaN
    
        2
  •  0
  •   keramat    3 年前

    使用:

    nind1 = df2.columns.values.copy()
    nind2 = np.unique(np.append(nind1, qindf1notdf2))
    deff = len(nind2)-len(nind1)
    for i, x in enumerate(nind2):
        if x in qindf1notdf2:
            nind2[nind2>=x] = [re.sub('\d', lambda s: str(int(s.group(0)) + 1), y) for y in nind2[nind2>=x]]
    
    ncols = nind2[:-deff]
    df2.columns = ncols
    pd.concat([df1, df2])
    

    输出:

    enter image description here

        3
  •  0
  •   mozway    3 年前

    您可以编写一个助手函数来自动重命名第二个数据帧。你所需要知道的就是遗漏问题的清单。我在这里用过 df1 作为名称的来源,但也可以使用连续的“Q1”、“Q2”Qn'。

    def rename(df, skip=[], ref=df1):
        skip = set(skip)
        cols = (c for c in ref.columns if c not in skip)
        return df.rename(columns=dict(zip(df.columns, cols)))
    
    pd.concat([df1, rename(df2, skip=['Q3', 'Q5'])], ignore_index=True)
    

    输出:

      Q1 Q2   Q3 Q4   Q5 Q6
    0  a  b    c  d    e  f
    1  a  b  NaN  d  NaN  f
    
    带有Qx生成器的辅助函数

    这一个完全依赖于位置,所以即使在df1中,如果名称不完美,也可以使用它

    def rename(df, skip=[]):
        skip = set(skip)
        cols = (f'Q{i}' for i in range(1, len(df.columns)+len(skip)+1)
                if i not in skip)
        return df.set_axis(cols, axis=1)
    
    pd.concat([rename(df1), rename(df2, skip=[3,5])], ignore_index=True)