Unpacking many columns of lists using apply get ValueError: If using all scalar values, you must pass an index

Unpacking many columns of lists using apply get ValueError: If using all scalar values, you must pass an index

我想将多列列表解压成更多列。基本上 用于列表的多列 而不是只有一个,并避免 for 循环。

例如我有一个 pandas.DataFrame,

import pandas as pd

tst = pd.DataFrame({'A': [[1, 2]]* 5, 'B': [[3, 4]]* 5, 'C': [[5, 6]] * 5})

我可以轻松解压其中一列,例如A 分成多列,

pd.DataFrame(tst['A'].to_list(), 
             columns=['1' + tst['A'].name, '2' + tst['A'].name],
             index=list(range(tst['A'].shape[0]))
            )

然而,当我尝试使用 .apply 将其扩展到多列以避免 for 循环时,

tst.apply(
    lambda x: pd.DataFrame(x.to_list(), 
                           columns=['1' + x.name, '2' + x.name], 
                           index=list(range(x.shape[0]))
                          )
)

我收到以下错误,但是我提供了 index...

ValueError: If using all scalar values, you must pass an index

有没有办法解决这个问题,让我得到如下所示的输出? (列顺序无关紧要)

    1C  2C  1B  2B  1A  2A
0   5   6   3   4   1   2
1   5   6   3   4   1   2
2   5   6   3   4   1   2
3   5   6   3   4   1   2
4   5   6   3   4   1   2

pd.__version__ == '1.0.5'

如果您不介意将 apply 更改为 explode 那么这是单行解决方案。氪

res=pd.concat([pd.DataFrame(tst[[x]].explode(x).values.reshape(-1,2), columns=['1' + x, '2' + x]) for x in tst.columns], 1)
print(res)

哪个returns:

  1A 2A 1B 2B 1C 2C
0  1  2  3  4  5  6
1  1  2  3  4  5  6
2  1  2  3  4  5  6
3  1  2  3  4  5  6
4  1  2  3  4  5  6

您可以水平 stack 列,然后创建一个新数据框并重命名列:

df = pd.DataFrame(np.hstack(tst.values.T.tolist()))
df.columns = [f'{i}{c}' for c in tst for i in range(1,3)]

或者您可以 concat 沿着 axis=1:

df = pd.concat([pd.DataFrame(tst[c].tolist()) for c in tst], axis=1)
df.columns = [f'{i}{c}' for c in tst for i in range(1,3)]

print(df)

   1A  2A  1B  2B  1C  2C
0   1   2   3   4   5   6
1   1   2   3   4   5   6
2   1   2   3   4   5   6
3   1   2   3   4   5   6
4   1   2   3   4   5   6