Pandas - 合并列并一个接一个地放置?

Pandas - combine columns and put one after another?

我有以下数据框:

a1,a2,b1,b2
1,2,3,4
2,3,4,5
3,4,5,6

理想的输出是:

a,b
1,3
2,4
3,5
2,4
3,5
4,6

dataframe中有很多"a"和"b"命名的headers,最大的是a50和b50。所以我正在寻找将它们全部组合成 "a" 和 "b".

的方法

我认为可以使用 concat,但我不知道如何将它们组合起来,将所有值放在一起。我将不胜感激。

首先我们读取数据帧:

import pandas as pd
from io import StringIO

s = """a1,a2,b1,b2
1,2,3,4
2,3,4,5
3,4,5,6"""

df = pd.read_csv(StringIO(s), sep=',')

然后我们把列堆叠起来,把列数和字母'a'或者'b'分开:

stacked = df.stack().rename("val").reset_index(1).reset_index()
cols_numbers = pd.DataFrame(stacked
                            .level_1
                            .str.split('(\d)')
                            .apply(lambda l: l[:2])
                            .tolist(), 
                            columns=["col", "num"])
x = cols_numbers.join(stacked[['val', 'index']])
print(x)
   col num  val  index
0    a   1    1      0
1    a   2    2      0
2    b   1    3      0
3    b   2    4      0
4    a   1    2      1
5    a   2    3      1
6    b   1    4      1
7    b   2    5      1
8    a   1    3      2
9    a   2    4      2
10   b   1    5      2
11   b   2    6      2

最后,我们按indexnum分组得到两列ab,我们填充b的第一行具有第二个值的列,以获得预期的结果:

result = (x
         .set_index("col", append=True)
         .groupby(["index", "num"])
         .val
         .apply(lambda g: 
                g
                .unstack()
                .fillna(method="bfill")
                .head(1))
         .reset_index(-1, drop=True))

print(result)
col          a    b
index num          
0     1    1.0  3.0
      2    2.0  4.0
1     1    2.0  4.0
      2    3.0  5.0
2     1    3.0  5.0
      2    4.0  6.0

最后去掉多索引:result.reset_index(drop=True)

您可以使用 pd.wide_to_long:

pd.wide_to_long(df.reset_index(), ['a','b'], 'index', 'No').reset_index()[['a','b']]

输出:

   a  b
0  1  3
1  2  4
2  3  5
3  2  4
4  3  5
5  4  6