Pandas重塑列集作为行

3

我有一个数据框,大致长这样:

A1 B1 C1 A4 B4 C4 A7 B7 C7
A2 B2 C2 A5 B5 C5 A8 B8 C8
A3 B3 C3 A6 B6 C6 A9 B9 C9

我希望你能将其翻译为以下内容:

我想让它看起来像这样:

A1 B1 C1
A2 B2 C2
A3 B3 C3
A4 B4 C4
A5 B5 C5
A6 B6 C6
A7 B7 C7
A8 B8 C8
A9 B9 C9

在pandas或其他数据处理库中,是否有任何内置功能可以在不手动遍历每个“列集”三次(在此示例中)的情况下轻松完成此操作?这实际上将是一个三列数据透视表。


1
你可以使用 df.values.reshape(-1,3) - Quang Hoang
@QuangHoang 检查他的输出顺序,reshape 无法解决。 - user3483203
4个回答

2

reshape + swapaxes + reshape


df.values.reshape(-1, 3, 3).swapaxes(1, 0).reshape(-1, 3)

array([['A1', 'B1', 'C1'],
       ['A2', 'B2', 'C2'],
       ['A3', 'B3', 'C3'],
       ['A4', 'B4', 'C4'],
       ['A5', 'B5', 'C5'],
       ['A6', 'B6', 'C6'],
       ['A7', 'B7', 'C7'],
       ['A8', 'B8', 'C8'],
       ['A9', 'B9', 'C9']], dtype=object)

为了更加通用,您可以根据分组计算偏移量。例如,在以下框架中,让我们将每4列分为一组:
A1 B1 C1 D1 A4 B4 C4 D4 A7 B7 C7 D7
A2 B2 C2 D2 A5 B5 C5 D5 A8 B8 C8 D8
A3 B3 C3 D3 A6 B6 C6 D6 A9 B9 C9 D9

n = 4
f = df.shape[1] // n

df.values.reshape(-1, f, n).swapaxes(1, 0).reshape(-1, n)

array([['A1', 'B1', 'C1', 'D1'],
       ['A2', 'B2', 'C2', 'D2'],
       ['A3', 'B3', 'C3', 'D3'],
       ['A4', 'B4', 'C4', 'D4'],
       ['A5', 'B5', 'C5', 'D5'],
       ['A6', 'B6', 'C6', 'D6'],
       ['A7', 'B7', 'C7', 'D7'],
       ['A8', 'B8', 'C8', 'D8'],
       ['A9', 'B9', 'C9', 'D9']], dtype=object)

使用底层数组将是一种非常快速的方法。
df = pd.concat([df]*500)

In [128]: %%timeit
     ...: n = 3
     ...: f = df.shape[1] // n
     ...: df.values.reshape(-1, f, n).swapaxes(1, 0).reshape(-1, n)
     ...:
77.4 µs ± 417 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [129]: %%timeit
     ...: c = np.arange(len(df.columns))
     ...: df.columns = [c // 3, c % 3]
     ...: df1 = df.stack(0).sort_index(level=1).reset_index(drop=True)
     ...:
     ...:
12.2 ms ± 326 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

1
使用DataFrame.stack与通过模数和整数除法创建的MultiIndex:
c = np.arange(len(df.columns))

df.columns = [c // 3, c % 3]
df1 = df.stack(0).sort_index(level=1).reset_index(drop=True)
print (df1)
RangeIndex(start=0, stop=3, step=1)
    0   1   2
0  A1  B1  C1
1  A2  B2  C2
2  A3  B3  C3
3  A4  B4  C4
4  A5  B5  C5
5  A6  B6  C6
6  A7  B7  C7
7  A8  B8  C8
8  A9  B9  C9

0
你可以重建 df:
import pandas as pd
from itertools import chain

letters = sorted(set(j for i in chain(*df.values) for j in i if j.isalpha()))
v = {letter: sorted(i for i in chain(*df.values) if i.startswith(letter)) for letter in letters}

dff = pd.DataFrame(v)
print(dff)

    A   B   C
0  A1  B1  C1
1  A2  B2  C2
2  A3  B3  C3
3  A4  B4  C4
4  A5  B5  C5
5  A6  B6  C6
6  A7  B7  C7
7  A8  B8  C8
8  A9  B9  C9

0

我在pandas方面没有太多经验,所以不知道确切的语法。但是你可以将原始数据框拆分成3个块,然后沿着第一轴重新连接为所需的数据框。

因此,它可以分成

A1 B1 C1
A2 B2 C2
A3 B3 C3

,

A4 B4 C4
A5 B5 C5
A6 B6 C6

,

A7 B7 C7
A8 B8 C8
A9 B9 C9

.


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