Pandas 从长到宽的子集
Pandas long to wide by subsets
我有以下格式的数据框
YR WEEK ACCOUNT Tax AMOUNT SURCHARGE Label
2021 1 1 10 5000 5 0
2021 1 2 20 10000 10 1
2021 2 1 20 2000 2 0
2021 2 2 5 10 3 1
2021 3 1 20 10000 10 1
2021 3 2 10 40000 50 1
我想重塑它,结果如下
ACCOUNT YR WEEK Tax_1 Amount_1 Surcharge_1 Tax_2 Amount_2 Surcharge_2 Label
1 2021 2 10 5000 5 20 2000 2 0
2 2021 2 20 10000 10 5 10 3 1
1 2021 3 0 2000 2 20 10000 10 1
2 2021 3 5 10 3 10 40000 50 1
每一行都是 reshaped
,因此它是过去 2 行(按帐户、年份和周)的函数。 Label
是 WEEK
的当前标签
我先尝试 reshape
到 wide
df.pivot('ACCOUNT', columns=['YR','WEEK'])
并打算在 reshape
之后尝试,但是 pivot
产生了 NaN
值
关于如何在 pandas
中实现此目标的任何想法
谢谢!
你想要的不是 pivot
,因为 pivot
重塑了数据,而你在这里想要 duplicate/shift 它(你之后比之前有更多的数据单元格)。
举一个更简单的例子,目标是从这样的事情开始(6 个值):
id group value
0 1 1 A
1 1 2 B
2 1 3 C
3 2 1 D
4 2 2 E
5 2 3 F
对此(8 个值):
id group_1 value_1 group_2 value_2
0 1 1 A 2 B
1 1 2 B 3 C
2 2 1 D 2 E
3 2 2 E 3 F
我们怎么做?
您可以通过对每个组进行选择并连接两个输出来实现您想要的效果:
cols = ['YR', 'ACCOUNT']
g = df.sort_values(by=['YR', 'WEEK']).groupby(cols)
out = (
pd.concat([g.apply(lambda d: d.drop(columns=cols+['WEEK']).iloc[:-1]).droplevel(-1).add_suffix('_1'),
g.apply(lambda d: d.drop(columns=cols).iloc[1:]).droplevel(-1).add_suffix('_2')
], axis=1)
.reset_index()
)
注意。 labels
的输出略有不同
输出:
YR ACCOUNT Tax_1 AMOUNT_1 SURCHARGE_1 Label_1 WEEK_2 Tax_2 AMOUNT_2 SURCHARGE_2 Label_2
0 2021 1 10 5000 5 0 2 20 2000 2 0
1 2021 1 20 2000 2 0 3 20 10000 10 1
2 2021 2 20 10000 10 1 2 5 10 3 1
3 2021 2 5 10 3 1 3 10 40000 50 1
精简版
注意。这要求没有 NaNs
cols = ['YR', 'ACCOUNT']
g = df.sort_values(by=['YR', 'WEEK']).groupby(cols)
pd.concat([g.shift().add_suffix('_1'), df.add_suffix('_2')], axis=1).dropna(how='any', axis=0)
我有以下格式的数据框
YR WEEK ACCOUNT Tax AMOUNT SURCHARGE Label
2021 1 1 10 5000 5 0
2021 1 2 20 10000 10 1
2021 2 1 20 2000 2 0
2021 2 2 5 10 3 1
2021 3 1 20 10000 10 1
2021 3 2 10 40000 50 1
我想重塑它,结果如下
ACCOUNT YR WEEK Tax_1 Amount_1 Surcharge_1 Tax_2 Amount_2 Surcharge_2 Label
1 2021 2 10 5000 5 20 2000 2 0
2 2021 2 20 10000 10 5 10 3 1
1 2021 3 0 2000 2 20 10000 10 1
2 2021 3 5 10 3 10 40000 50 1
每一行都是 reshaped
,因此它是过去 2 行(按帐户、年份和周)的函数。 Label
是 WEEK
的当前标签
我先尝试 reshape
到 wide
df.pivot('ACCOUNT', columns=['YR','WEEK'])
并打算在 reshape
之后尝试,但是 pivot
产生了 NaN
值
关于如何在 pandas
中实现此目标的任何想法
谢谢!
你想要的不是 pivot
,因为 pivot
重塑了数据,而你在这里想要 duplicate/shift 它(你之后比之前有更多的数据单元格)。
举一个更简单的例子,目标是从这样的事情开始(6 个值):
id group value
0 1 1 A
1 1 2 B
2 1 3 C
3 2 1 D
4 2 2 E
5 2 3 F
对此(8 个值):
id group_1 value_1 group_2 value_2
0 1 1 A 2 B
1 1 2 B 3 C
2 2 1 D 2 E
3 2 2 E 3 F
我们怎么做?
您可以通过对每个组进行选择并连接两个输出来实现您想要的效果:
cols = ['YR', 'ACCOUNT']
g = df.sort_values(by=['YR', 'WEEK']).groupby(cols)
out = (
pd.concat([g.apply(lambda d: d.drop(columns=cols+['WEEK']).iloc[:-1]).droplevel(-1).add_suffix('_1'),
g.apply(lambda d: d.drop(columns=cols).iloc[1:]).droplevel(-1).add_suffix('_2')
], axis=1)
.reset_index()
)
注意。 labels
的输出略有不同输出:
YR ACCOUNT Tax_1 AMOUNT_1 SURCHARGE_1 Label_1 WEEK_2 Tax_2 AMOUNT_2 SURCHARGE_2 Label_2
0 2021 1 10 5000 5 0 2 20 2000 2 0
1 2021 1 20 2000 2 0 3 20 10000 10 1
2 2021 2 20 10000 10 1 2 5 10 3 1
3 2021 2 5 10 3 1 3 10 40000 50 1
精简版
注意。这要求没有 NaNs
cols = ['YR', 'ACCOUNT']
g = df.sort_values(by=['YR', 'WEEK']).groupby(cols)
pd.concat([g.shift().add_suffix('_1'), df.add_suffix('_2')], axis=1).dropna(how='any', axis=0)