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.filter
与 pd.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
采用模式,并相应地重塑数据。
我有一个 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.filter
与 pd.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
采用模式,并相应地重塑数据。