我有一个数据框:
Amount dwy bmd
Portfolio EUR GBP JPY USD EUR GBP JPY USD EUR GBP JPY USD
date
2016-05-13 100 200 300 400 -0.5 0.5 0 0.8 3.8 3 0 3
Run Code Online (Sandbox Code Playgroud)
我想把它转移到这个:
date ccy amt dwy bmd
2016-05-13 EUR 100 -0.5 3.8
2016-05-13 GBP 200 0.5 3
2016-05-13 JPY 300 0 0
2016-05-13 USD 400 0.8 3
Run Code Online (Sandbox Code Playgroud)
我已经尝试过df.stack()并且df.unstack也df.T以多种方式尝试过。除了将它一块一块地拆开并重新组装之外,还有没有更好的方法?
pd.DataFrame(df.stack("Currency").to_records()) 应该做的伎俩。
以下是步骤的解释:
1. 重现您的数据框:
arrays = [['Amount', 'Amount', 'Amount', 'Amount', 'dwy', 'dwy', 'dwy', 'dwy', 'bmd', 'bmd', 'bmd', 'bmd'],
['EUR', 'GBP', 'JPY', 'USD', 'EUR', 'GBP', 'JPY', 'USD', 'EUR', 'GBP', 'JPY', 'USD']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['Portfolio', 'Currency'])
data = [100, 200, 300, 400, -0.5, 0.5, 0, 0.8, 3.8, 3, 0, 3]
df = pd.DataFrame(data).T
df.columns = index
df.index = ['2016-05-13']
Run Code Online (Sandbox Code Playgroud)
这是“输入”数据帧:
Portfolio Amount dwy bmd
Currency EUR GBP JPY USD EUR GBP JPY USD EUR GBP JPY USD
2016-05-13 100 200 300 400 -0.5 0.5 0 0.8 3.8 3 0 3
Run Code Online (Sandbox Code Playgroud)
2. 调用df.stack("Currency")会堆叠在货币列上:
Portfolio Amount bmd dwy
Currency
2016-05-13 EUR 100 3.8 -0.5
GBP 200 3.0 0.5
JPY 300 0.0 0.0
USD 400 3.0 0.8
Run Code Online (Sandbox Code Playgroud)
3.关闭但不完全。我们只需要展平 Dataframe 的索引。为此,我们可以调用to_records():
3. df.stack("Currency").to_records()
# Result:
# => rec.array([('2016-05-13', 'EUR', 100.0, 3.8, -0.5),
('2016-05-13', 'GBP', 200.0, 3.0, 0.5),
('2016-05-13', 'JPY', 300.0, 0.0, 0.0),
('2016-05-13', 'USD', 400.0, 3.0, 0.8)],
dtype=[('level_0', 'S10'), ('Currency', 'S3'), ('Amount', '<f8'), ('bmd', '<f8'), ('dwy', '<f8')])
Run Code Online (Sandbox Code Playgroud)
4. 然后我们可以使用新索引重新创建数据框:
pd.DataFrame(df.stack("Currency").to_records())
level_0 Currency Amount bmd dwy
0 2016-05-13 EUR 100 3.8 -0.5
1 2016-05-13 GBP 200 3.0 0.5
2 2016-05-13 JPY 300 0.0 0.0
3 2016-05-13 USD 400 3.0 0.8
Run Code Online (Sandbox Code Playgroud)
从这里,您可以根据需要简单地重命名和重新排序您的列。