Pandas 基于第一列值的 DataFrame 从宽到长

Pandas DataFrame Wide to Long based on first column values

我想转换以下宽格式的 Pandas DataFrame

df = pd.DataFrame([['A', '1', '2', '3'], ['B', '4', '5', '6'], ['C', '7', '8', '9']], columns=['ABC', 'def', 'ghi', 'jkl'])

df =
   ABC  def  ghi  jkl
0    A    1    2    3
1    B    4    5    6
2    C    7    8    9

转换为长格式,其中第一列中的值仍然对应于小写列中的值。列名称不能用作存根名称。新列的名称无关紧要,以后可以重命名。

输出应如下所示:

df =
   0  1
0  A  1
1  A  2
2  A  3
3  B  4
4  B  5
5  B  6
6  C  7
7  C  8
8  C  9

我不确定如何最好、最有效地做到这一点。这可以用 wide_to_long() 来完成吗?那么我就不知道如何处理存根名称了。最好的是可以在大型 table.

上使用的高效单线纸

非常感谢!!

您可以使用 df.stack:

>>> df.set_index('ABC') \
      .stack() \
      .reset_index(level='ABC') \
      .reset_index(drop=True)

  ABC  0
0   A  1
1   A  2
2   A  3
3   B  4
4   B  5
5   B  6
6   C  7
7   C  8
8   C  9

或按照@MustafaAydın 的建议使用df.melt

>>> df.melt('ABC') \
      .sort_values('ABC') \
      .drop(columns='variable') \
      .reset_index(drop=True)

  ABC value
0   A     1
1   A     2
2   A     3
3   B     4
4   B     5
5   B     6
6   C     7
7   C     8
8   C     9

使用 DataFrame.melt with DataFrame.sort_index 并删除 variable 列:

df1 = (df.melt("ABC", value_name='new', ignore_index=False)
          .sort_index(ignore_index=True)
          .drop('variable', axis=1)
         )
print (df1)
  ABC new
0   A   1
1   A   2
2   A   3
3   B   4
4   B   5
5   B   6
6   C   7
7   C   8
8   C   9

如果需要生成列名称的第一个值的更多动态解决方案:

first = df.columns[0]
df1 = (df.melt(first, value_name='new', ignore_index=False)
         .sort_index(ignore_index=True)
         .drop('variable', axis=1))