如何通过索引重塑多列数据框?

3

根据这里的内容。该解决方案仅适用于单个列。如何将解决方案改进以处理多个列,即如果我有一个数据框:

df= pd.DataFrame([['a','b'],['b','c'],['c','z'],['d','b']],index=[0,0,1,1])
   0  1   2   3
0  a  b   b   c 
1  c  z   d   b

如何将它们改为这样的形式

  0   1  2  3
0  a  b  b  c 
1  c  z  d  b

如果 df 是

   0  1
0  a  b
1  c  z
1  d  b

那么

   0  1   2   3
0  a  b NaN NaN
1  c  z   d   b
4个回答

3

使用flatten/ravel函数

In [4401]: df.groupby(level=0).apply(lambda x: pd.Series(x.values.flatten()))
Out[4401]:
   0  1  2  3
0  a  b  b  c
1  c  z  d  b

或者,堆栈
In [4413]: df.groupby(level=0).apply(lambda x: pd.Series(x.stack().values))
Out[4413]:
   0  1  2  3
0  a  b  b  c
1  c  z  d  b

同样,使用不相等的索引
In [4435]: df.groupby(level=0).apply(lambda x: x.values.ravel()).apply(pd.Series)
Out[4435]:
   0  1    2    3
0  a  b  NaN  NaN
1  c  z    d    b

1
更新了解决方案。 - Zero

2

使用 groupby + pd.Series + np.reshape:

df.groupby(level=0).apply(lambda x: pd.Series(x.values.reshape(-1, )))

   0  1  2  3
0  a  b  b  c
1  c  z  d  b

解决不同数量的索引问题 - 调用 pd.DataFrame 构造函数即可。
df

   0  1
0  a  b
1  c  z
1  d  b

df.groupby(level=0).apply(lambda x: \
      pd.DataFrame(x.values.reshape(1, -1))).reset_index(drop=True)

   0  1    2    3
0  a  b  NaN  NaN
1  c  z    d    b

为什么在索引不相等的情况下,groupby返回Series? - Bharath M Shetty
@Bharathshetty 现在可以工作了...我想。 - cs95
是的,它有效。一开始有点困惑为什么系列被重置为索引(drop=True),后来意识到它是数据框。 - Bharath M Shetty
你知道我为什么有系列吗? - Bharath M Shetty
@Bharathshetty 我的猜测是,它不知道如何处理不相��的元素,所以它将其沿长度重塑。使用第二种解决方案,我们明确地使其成为二维数组(通过指定大小为1的第二个维度)。 - cs95

2
pd.DataFrame({n: g.values.ravel() for n, g in df.groupby(level=0)}).T

   0  1  2  3
0  a  b  b  c
1  c  z  d  b

这些内容有点杂乱无章,我太累了,没有精力美化它们。

v = df.values
cc = df.groupby(level=0).cumcount().values
i0, r = pd.factorize(df.index.values)
n, m = v.shape
j0 = np.tile(np.arange(m), n)
j = np.arange(r.size * m).reshape(-1, m)[cc].ravel()
i = i0.repeat(m)

e = np.empty((r.size, m * r.size), dtype=object)

e[i, j] = v.ravel()

pd.DataFrame(e, r)

   0  1     2     3
0  a  b  None  None
1  c  z     d     b

先生,数组必须具有相同的长度是一个要求。当索引不相等时,这将无法运行。 - Bharath M Shetty
1
是的,我看到了。正在处理中。 - piRSquared
啊,你在这里把循环从应用中去掉了。 - cs95
先生,pd.DataFrame(df.set_index(df.groupby(level=0).cumcount(), append=True).unstack().values) 这个代码也可以重塑数据,但是索引没有被保留。您能否对此进行处理? - Bharath M Shetty

1

让我们来试试

df1 = df.set_index(df.groupby(level=0).cumcount(), append=True).unstack()
df1.set_axis(labels=pd.np.arange(len(df1.columns)), axis=1)

输出:

   0  1  2  3
0  a  b  b  c
1  c  d  z  b

df的NaN输出:

   0     1  2     3
0  a  None  b  None
1  c     d  z     b

1
set_axis 是 Pandas 中为数不多的原地操作之一。然而,在下一个 Pandas 版本中,我认为 set_axis 将会添加一个 inplace 参数。https://github.com/pandas-dev/pandas/pull/16994 - Scott Boston

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