Pandas 堆栈列对

Pandas stack column pairs

我有一个 pandas 数据框,其中包含大约 100 列以下类型:

X1       Y1      X2      Y2      X3      Y3
 0.78    0.22    0.19    0.42    0.04    0.65 
 0.43    0.29    0.43    0.84    0.14    0.42 
 0.57    0.70    0.59    0.86    0.11    0.40 
 0.92    0.52    0.81    0.33    0.54    1.00 

w1here (X,Y) 基本上是值对

我需要从上面创建以下内容。

   X     Y
 0.78    0.22 
 0.43    0.29 
 0.57    0.70 
 0.92    0.52 
 0.19    0.42 
 0.43    0.84 
 0.59    0.86 
 0.81    0.33 
 0.04    0.65 
 0.14    0.42 
 0.11    0.40 
 0.54    1.00 

即堆叠所有奇数的 X 列,然后堆叠所有偶数的 Y 列。

我什至不知道从哪里开始。对于少量的列,我可以很容易地使用列名。

您可以使用 lreshape,列名使用 list comprehension:

x = [col for col in df.columns if 'X' in col]
y = [col for col in df.columns if 'Y' in col]

df = pd.lreshape(df, {'X': x,'Y': y})
print (df)
       X     Y
0   0.78  0.22
1   0.43  0.29
2   0.57  0.70
3   0.92  0.52
4   0.19  0.42
5   0.43  0.84
6   0.59  0.86
7   0.81  0.33
8   0.04  0.65
9   0.14  0.42
10  0.11  0.40
11  0.54  1.00

MultiIndexstack 的解决方案:

df.columns = [np.arange(len(df.columns)) % 2, np.arange(len(df.columns)) // 2]
df = df.stack().reset_index(drop=True)
df.columns = ['X','Y']
print (df)
       X     Y
0   0.78  0.22
1   0.19  0.42
2   0.04  0.65
3   0.43  0.29
4   0.43  0.84
5   0.14  0.42
6   0.57  0.70
7   0.59  0.86
8   0.11  0.40
9   0.92  0.52
10  0.81  0.33
11  0.54  1.00

可能还值得注意的是,您可以只使用 X-Y 值显式构造一个新的 DataFrame。这很可能会更快,但它假定 X-Y​​ 列对是您的 DataFrame 的全部。

pd.DataFrame(dict(X=df.values[:,::2].reshape(-1),
                  Y=df.values[:,1::2].reshape(-1)))

演示

>>> pd.DataFrame(dict(X=df.values[:,::2].reshape(-1),
                      Y=df.values[:,1::2].reshape(-1)))

       X     Y
0   0.78  0.22
1   0.19  0.42
2   0.04  0.65
3   0.43  0.29
4   0.43  0.84
5   0.14  0.42
6   0.57  0.70
7   0.59  0.86
8   0.11  0.40
9   0.92  0.52
10  0.81  0.33
11  0.54  1.00

您可以使用已记录的 pd.wide_to_long,但您需要使用 'dummy' 列来唯一标识每一行。您可以稍后删除此列。

pd.wide_to_long(df.reset_index(), 
                stubnames=['X', 'Y'], 
                i='index', 
                j='dropme').reset_index(drop=True)

       X     Y
0   0.78  0.22
1   0.43  0.29
2   0.57  0.70
3   0.92  0.52
4   0.19  0.42
5   0.43  0.84
6   0.59  0.86
7   0.81  0.33
8   0.04  0.65
9   0.14  0.42
10  0.11  0.40
11  0.54  1.00