`pandas.concat`在输入为字典时是如何工作的?

3 投票
2 回答
59 浏览
提问于 2025-04-14 15:24

我在理解当输入是字典时,pd.concat是怎么工作的,感到有些困惑。

假设我们有一个这样的pandas数据框 -

# Import pandas library
import pandas as pd

# initialize list of lists
data = [['tom', 10], ['nick', 15], ['juli', 14]]

# Create the pandas DataFrame
df = pd.DataFrame(data, columns=['Name', 'Age'])

然后,我们进行以下的拼接操作 -

z = pd.concat({"z":df},
              axis = 1)

print(z)

输出结果是 -

      z    
   Name Age
0   tom  10
1  nick  15
2  juli  14

看起来像是键z被叠加到了数据框df的上面。但这不太合理,因为指定的轴是1,所以如果真的是叠加的话,应该是在列之间进行的。

2 个回答

0
z = pd.concat({"z": df}, axis=1)

在上面的代码中,你提供了一个字典,这个字典里有一个键 z,对应的值是一个数据表 df。当你沿着 axis=1 进行合并时,Pandas 会根据数据表的索引来对齐这些数据表。你的数据表 df 的索引是 [0, 1, 2],而字典的键 z 没有索引,所以它被当作一个额外的层级,加入到结果的多重索引中,位于列的部分。

因此,最终得到的数据表 z 有一个多重索引的列,最上面一层叫做 z,下面一层对应的是原始数据表 df 的列。这就是为什么你在输出中看到键 z 在数据表 df 的上面。其实并不是说键 z 堆在 df 上面,而是它作为列索引中的一个层级被包含进去了。

如果你想在列之间合并,而不想在多重索引中添加额外的层级,可以这样做:

z = pd.concat([df], axis=1)

输出:

   Name  Age
0   tom   10
1  nick   15
2  juli   14
5

这其实是有道理的,因为你是在的方向上拼接(axis=1),所以你需要区分这些拼接后的列。

这里有一个更有意义的例子:

out = pd.concat({'left': df.add_prefix('left_'),
                 'middle': df.add_prefix('middle_'),
                 'right': df.add_prefix('right_')},
                axis=1)

       left               middle                 right          
  left_Name left_Age middle_Name middle_Age right_Name right_Age
0       tom       10         tom         10        tom        10
1      nick       15        nick         15       nick        15
2      juli       14        juli         14       juli        14

这就相当于把新的名字传给keys

out = pd.concat([df.add_prefix('left_'),
                 df.add_prefix('middle_'),
                 df.add_prefix('right_')],
                keys=['left', 'middle', 'right'],
                axis=1)

如果你是在axis=0(行)的方向上拼接,那么concat会在前面加一个索引级别:

out = pd.concat({'top': df,
                 'middle': df,
                 'bottom': df},
                 axis=0)

          Name  Age
top    0   tom   10
       1  nick   15
       2  juli   14
middle 0   tom   10
       1  nick   15
       2  juli   14
bottom 0   tom   10
       1  nick   15
       2  juli   14

撰写回答