Pandas DataFrame按列标题将编号的列分成行



我有一个DataFrame,看起来像这样:

df = pd.DataFrame({
'A': [0, 1, 2, 3, 4],
'B': ['a', 'b', 'c', 'd', 'e'],
'V1': [0.0, 0.1, 0.2, 0.3, 0.4],
'V2': [1.0, 1.1, 1.2, 1.3, 1.4],
'V3': [2.0, 2.1, 2.2, 2.3, 2.4],
'X': ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
})
A  B   V1   V2   V3        X
0  0  a  0.0  1.0  2.0    alpha
1  1  b  0.1  1.1  2.1     beta
2  2  c  0.2  1.2  2.2    gamma
3  3  d  0.3  1.3  2.3    delta
4  4  e  0.4  1.4  2.4  epsilon

我想使用V列中的数字将其展开到一个长表格中。列标签中的数字(1表示V1, 2表示V2等)将成为名为"V number"的列中的新列值。或者其他的值将是唯一的"在那一排。像这样(我在这里隐藏了索引,因为我不关心它):

A  B  V Number    V        X
0  a      1     0.0    alpha     # Old first row, V1 value
0  a      2     1.0    alpha     # Old first row, V2 value
0  a      3     2.0    alpha     # Old first row, V3 value
1  b      1     0.1     beta     # Old second row, V1 value
1  b      2     1.1     beta     # etc...
1  b      3     2.1     beta
2  c      1     0.2    gamma
2  c      2     1.2    gamma
2  c      3     2.2    gamma
3  d      1     0.3    delta
3  d      2     1.3    delta
3  d      3     2.3    delta
4  e      1     0.4  epsilon
4  e      2     1.4  epsilon
4  e      3     2.4  epsilon

在真实的DataFrame中有超过40个"V"列,超过100个其他列和几千行,所以一个合理的简单和快速的方法会很好!如果有帮助的话,列名称很容易隔离(它们实际上被称为例如Test Voltage (3)',但出于示例的目的,我缩短了它们),例如[i for i in df.columns if 'Test Voltage' in i]

有没有人想到一个简单的方法来做这件事?我试着寻找很多方法,但一直在寻找方法来分割列与单元格中的列表。

尝试使用wide_to_long

out = pd.wide_to_long(df,['V'],i=['A','B','X'],j='number').reset_index()
Out[23]: 
A  B        X  number    V
0   0  a    alpha       1  0.0
1   0  a    alpha       2  1.0
2   0  a    alpha       3  2.0
3   1  b     beta       1  0.1
4   1  b     beta       2  1.1
5   1  b     beta       3  2.1
6   2  c    gamma       1  0.2
7   2  c    gamma       2  1.2
8   2  c    gamma       3  2.2
9   3  d    delta       1  0.3
10  3  d    delta       2  1.3
11  3  d    delta       3  2.3
12  4  e  epsilon       1  0.4
13  4  e  epsilon       2  1.4
14  4  e  epsilon       3  2.4

使用melt:

>>> df.melt(id_vars=['A', 'B', 'X'], var_name='V Number', value_name='V')
A  B        X V Number    V
0   0  a    alpha       V1  0.0
1   1  b     beta       V1  0.1
2   2  c    gamma       V1  0.2
3   3  d    delta       V1  0.3
4   4  e  epsilon       V1  0.4
5   0  a    alpha       V2  1.0
6   1  b     beta       V2  1.1
7   2  c    gamma       V2  1.2
8   3  d    delta       V2  1.3
9   4  e  epsilon       V2  1.4
10  0  a    alpha       V3  2.0
11  1  b     beta       V3  2.1
12  2  c    gamma       V3  2.2
13  3  d    delta       V3  2.3
14  4  e  epsilon       V3  2.4

您也可以使用.stack(),如下所示:

(df.set_index(['A', 'B', 'X'])
.rename_axis(columns='V Number')
.stack()
.reset_index(name='V')
)

结果:

A  B        X V Number    V
0   0  a    alpha       V1  0.0
1   0  a    alpha       V2  1.0
2   0  a    alpha       V3  2.0
3   1  b     beta       V1  0.1
4   1  b     beta       V2  1.1
5   1  b     beta       V3  2.1
6   2  c    gamma       V1  0.2
7   2  c    gamma       V2  1.2
8   2  c    gamma       V3  2.2
9   3  d    delta       V1  0.3
10  3  d    delta       V2  1.3
11  3  d    delta       V3  2.3
12  4  e  epsilon       V1  0.4
13  4  e  epsilon       V2  1.4
14  4  e  epsilon       V3  2.4

如果您希望V Number列只有数字,您可以使用:

df2 = (df.set_index(['A', 'B', 'X'])
.rename_axis(columns='V Number')
.stack()
.reset_index(name='V')
)
df2['V Number'] = df2['V Number'].str[1:]

结果:

print(df2)
A  B        X V Number    V
0   0  a    alpha        1  0.0
1   0  a    alpha        2  1.0
2   0  a    alpha        3  2.0
3   1  b     beta        1  0.1
4   1  b     beta        2  1.1
5   1  b     beta        3  2.1
6   2  c    gamma        1  0.2
7   2  c    gamma        2  1.2
8   2  c    gamma        3  2.2
9   3  d    delta        1  0.3
10  3  d    delta        2  1.3
11  3  d    delta        3  2.3
12  4  e  epsilon        1  0.4
13  4  e  epsilon        2  1.4
14  4  e  epsilon        3  2.4

最新更新