Pandas - 将名称和列数不同的数据框堆叠在一起

3
我试图从两个完全不同的数据框中创建一个 csv 日志,因此我不能简单地连接/合并它们。第一个数据框只有一个数据点行,列数比第二个数据框多,而第二个数据框有许多数据点行。我还想在它们之间添加一个空白行以增加一些清晰度。是否有一种方法将它们组合起来,使得第二个数据框的空单元格获得 NaN 值?
考虑下面的简化示例:
数据框 1:
    Col A  Col B  Col C  Col D  Col E
0    XYZ    452   GHJ    089     IUT   

数据框架 2:

    Data1  Data2  Data3  Data4
0   1234   4567   7890   6543      
1   8765   4565   8767   0987
..
n   4387   0943   4598   3212

输出:

    Col A  Col B  Col C  Col D  Col E
0    XYZ    452   GHJ    089     IUT     
1    NaN    NaN   NaN    NaN     NaN
2    1234   4567  7890   6543    NaN
3    8765   4565  8767   0987    NaN
..
n    4387   0943  4598   3212    NaN
4个回答

3

满足您的需求。

  1. 将第二个数据帧的列拼接成与第一个数据帧相同的宽度,以避免变宽
  2. 然后使用concat()函数将它们连接起来,在第一个数据帧中的第一列前插入一个新的数据帧作为占位符np.nan
import numpy as np
df1 = pd.DataFrame({"Col A":["XYZ"],"Col B":[452],"Col C":[" GHJ"],"Col D":[89],"Col E":[" IUT"]})
df2 = pd.DataFrame({"Data1":[1234,8765,4387],"Data2":[4567,4565,943],"Data3":[7890,8767,4598],"Data4":[6543,987,3212]})
df2.columns=[df1.columns[i] for i,c in enumerate(df2.columns) if i<len(df1.columns)]

pd.concat([
    df1,
    pd.DataFrame({df1.columns[0]:[np.nan]}),
    df2
])

输出

Col A   Col B Col C   Col D Col E
  XYZ   452.0   GHJ    89.0   IUT
  NaN     NaN   NaN     NaN   NaN
 1234  4567.0  7890  6543.0   NaN
 8765  4565.0  8767   987.0   NaN
 4387   943.0  4598  3212.0   NaN

谢谢您。我喜欢它的易读性,可以很容易地看出您正在添加空数据框,以防将来有人想要删除/添加它。 - bloo

3
使用 DataFrame.set_axis 方法,设定 axis=1 参数将 df2 的列与 df1 一致,然后使用带有可选参数 ignore_index=Truepd.concat 方法将其与数据框 df1 连接:
df = pd.concat([df1.append(pd.Series(), ignore_index=True),
                df2.set_axis(df1.columns[:df2.shape[1]], axis=1)], ignore_index=True)

结果:

print(df)
  Col A   Col B Col C   Col D Col E
0   XYZ   452.0   GHJ    89.0   IUT
1   NaN     NaN   NaN     NaN   NaN
2  1234  4567.0  7890  6543.0   NaN
3  8765  4565.0  8767   987.0   NaN
4  4387   943.0  4598  3212.0   NaN

1
非常出色的答案,与被接受的答案一样好,我可以从你的答案中学到很多。我只是按照先来后到的原则做出选择,以公平为依据。 - bloo
1
@bloo 不用担心,愉快地编程吧 ;)。 - Shubham Sharma

2

这里有一个你可以尝试的方法:

m = df1.iloc[:,:df2.shape[1]].append(pd.Series(), ignore_index=True)
out = pd.DataFrame(np.vstack((m,df2)),columns=m.columns).join(df1.iloc[:,df2.shape[1]:])

print(out)

  Col A Col B Col C Col D Col E
0   XYZ   452   GHJ    89   IUT
1   NaN   NaN   NaN   NaN   NaN
2  1234  4567  7890  6543   NaN
3  8765  4565  8767   987   NaN
......
......

所采取的方法:

  • 根据第二个数据框的shape[1]将第一个数据框切片,并添加一行空白
  • 使用np.vstack创建堆叠数组并调用数据框构造函数
  • 使用第一个切片的列名,因为我们希望从第一个数据框获取列名
  • 将剩余的列加入数据框。

1
如果你真的想在一行中完成它:
df = pd.concat([df1.rename({x: i for i, x in enumerate(df1.columns)}, axis=1), df2.rename({x: i for i, x in enumerate(df2.columns)}, axis=1)]).rename({i: x for i, x in enumerate(df1.columns)}, axis=1)
代码分为以下几部分:
重命名两个数据框的列为0 -> len(columns)
连接数据框
将列重命名为第一个数据框的列
我个人会将其拆分为步骤:
df1_renamed = df1.rename({x: i for i, x in enumerate(df1.columns)}, axis=1)
df2_renamed = df2.rename({x: i for i, x in enumerate(df2.columns)}, axis=1)
df = pd.concat([df1_renamed, df2_renamed])
df.rename({i: x for i, x in enumerate(df1.columns)}, axis=1, inplace=True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接