Pandas 如何将以 3 为一组的列旋转成行

Pandas How to Pivot columns that come in sets of 3 into rows

我有一个 pandas df 需要转换和旋转。每个季节都有 3 列与之关联(开始、结束和费率)。我希望旋转这些列,最后只有 3 列开始、结束和速率

df:

ID S1start  S1end  Rate  S2start  S2end   Rate  S3start  S3end  Rate  S4start  S4end  Rate
1  1/1/21  1/31/21  80   2/1/21  2/28/21   85   3/1/21  3/31/21  90   4/1/21  4/30/21  95

决赛:

 ID  Start     End   Rate
  1  1/1/21  1/31/21  80
  1  2/1/21  2/28/21  85
  1  3/1/21  3/31/21  90
  1  4/1/21  4/30/21  95

尝试使用 reshape ,如果格式前缀为

out = pd.DataFrame(df.values.reshape((-1,3)), columns=['start','end','rate'])
Out[419]: 
    start      end rate
0  1/1/21  1/31/21   80
1  2/1/21  2/28/21   85
2  3/1/21  3/31/21   90
3  4/1/21  4/30/21   95

您可以将 df.filterpd.concat 一起使用:

In [589]: start = df.stack().filter(like='start').reset_index()[0]    
In [590]: end = df.stack().filter(like='end').reset_index()[0]
In [591]: rate = df.stack().filter(like='Rate').reset_index()[0]

In [594]: x = pd.concat([start.rename('Start'), end.rename('End'), rate.rename('Rate')], 1)

假设您有 2 个静态列:ID, PropCode。您可以像这样将这些列附加到 x

In [640]: x[['ID', 'PropCode']] = df[['ID', 'PropCode']].values.tolist() * len(x)

In [641]: x
Out[641]: 
    Start      End Rate  ID  PropCode
0  1/1/21  1/31/21   80   1     52032
1  2/1/21  2/28/21   85   1     52032
2  3/1/21  3/31/21   90   1     52032
3  4/1/21  4/30/21   95   1     52032

您可以使用 pivot_longer function from pyjanitor; at the moment you have to install the latest development version from github:

您分享的数据有规律(有些列以 start 结尾,有些以 end 结尾,有些以 Rate 开头),我们可以使用这些模式来重塑数据;

# install latest dev version
# pip install git+https://github.com/ericmjl/pyjanitor.git
 import janitor
df.pivot_longer(
    index="ID",
    names_pattern=("start$", "end$", "^Rate"),
    names_to=("Start", "End", "Rate"),
)

   ID   Start    End    Rate
0   1   1/1/21  1/31/21 80
1   1   2/1/21  2/28/21 85
2   1   3/1/21  3/31/21 90
3   1   4/1/21  4/30/21 95

names_to 采用新名称,而 names_pattern 采用模式,并相应地重塑数据。