我想展平 pandas 中的数据框。这基本上是通过使用列的出现/顺序的前缀/后缀来复制列名,并且创建的额外列的数量应基于行数。
例如:
`
df = pd.DataFrame({
'id': [1, 2, 3, 4],
'A': [10, 20, 30, 40],
'B': [50, 60, 70, 80],
'C': [90, 100, 110, 120]
})
print(df)
# id A B C
# 0 1 10 50 90
# 1 2 20 60 100
# 2 3 30 70 110
# 3 4 40 80 120
#I want something like the following.
print(result_df)
# id1 A1 B1 C1 id2 A2 B2 C2 id3 A3 B3 C3 id4 A4 B4 C4
# 0 1 10 50 90 2 20 60 100 3 30 70 110 4 40 80 120
`
试试这个:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'id': [1, 2, 3, 4],
'A': [10, 20, 30, 40],
'B': [50, 60, 70, 80],
'C': [90, 100, 110, 120]
})
df_out = df.unstack().to_frame().T.sort_index(level=0)
df_out.columns = [f'{i}{j+1}' for i, j in df_out.columns]
print(df_out)
输出:
id1 id2 id3 id4 A1 A2 A3 A4 B1 B2 B3 B4 C1 C2 C3 C4
0 1 2 3 4 10 20 30 40 50 60 70 80 90 100 110 120
df.unstack().to_frame().T
id A B C 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 4 10 20 30 40 50 60 70 80 90 100 110 120
.unstack()
方法返回一系列,然后.to_frame()
将其转换为具有一列的数据帧,最后.T
将此列转置为行。
@ScottBoston 的解决方案可以完成这项工作,只需进行一些修改:
df = pd.DataFrame({
'id': [1, 2, 3, 4],
'A': [10, 20, 30, 40],
'B': [50, 60, 70, 80],
'C': [90, 100, 110, 120],
})
def key_fn(keys):
"""Modify `id` key to ensure the top of the list"""
try:
keys = keys.str.replace("^id$", " id", regex=True)
except AttributeError:
# Ignore if regex doesn't suits, this occurs at level 1
pass
return keys
df_out = df.unstack().to_frame().sort_index(level=[1, 0], key=key_fn).T
df_out.columns = [f'{i}{j+1}' for i, j in df_out.columns]
print(df_out)
id1 A1 B1 C1 id2 A2 B2 C2 id3 A3 B3 C3 id4 A4 B4 C4
1 10 50 90 2 20 60 100 3 30 70 110 4 40 80 120
sort_index()
默认对索引进行排序,但通过.T
转置后索引位于axis=1
。一种解决方法是排序后转置,就像我在这里所做的那样。level
必须通过首先按级别 1 (行=(0, 1, 2, 3)) 对 DataFrame 进行排序来指定,然后按级别 0 (列=(id, A, B, C)) => level=[1, 0]
。key_fn
为列 id 预先添加一个空格。