只需接近熊猫中的层次列。原始数据帧(df)包含27列,如下所示(股票代码为索引):
Report Date Shares Gross Profit ...
Ticker
AAPL 2010-07-31 347000000.0 543000000.0 ...
AAPL 2010-10-31 344000000.0 548000000.0 ...
AAPL 2011-01-31 347000000.0 556000000.0 ...
AAPL 2011-04-30 347000000.0 580000000.0 ...
AAPL 2011-07-31 348000000.0 591000000.0 ...
我想修改列结构,以使第一级为报告日期,第二级为 Shares 和毛利润强>。我尝试仅使用一个股票代码(AAPL)来创建具有此结构的新数据框,这是我使用的代码:
col = pd.MultiIndex.from_product([df['Report Date'], df[['Shares', 'Gross Profit']]])
df1 = pd.DataFrame(df.loc['AAPL'], columns=col)
似乎很有效,但是只有NaN:
Report Date 2010-07-31 2010-10-31 \
Shares Gross Profit Shares Gross Profit
Ticker
AAPL NaN NaN NaN NaN
AAPL NaN NaN NaN NaN
AAPL NaN NaN NaN NaN
AAPL NaN NaN NaN NaN
此外,形状爆炸为(78,112668)。有人可以发现错误吗?我猜它在MultiIndex.from_product中,但是不知道在哪里。
答案 0 :(得分:0)
如果我们的目标是首先生成所需输出的转置版本,则可以用df.melt()解决此问题。您可以轻松地在MultiIndex
之前设置双层df.transpose()
。
df_want = df.melt(id_vars="Report Date", value_vars=["Shares", "Gross Profit"])\
.sort_values(["Report Date", "variable"])\
.set_index(["Report Date", "variable"])\
.transpose()
print(df_want)
Report Date 2010-07-31 ... 2011-07-31
variable Gross Profit Shares ... Gross Profit Shares
value 543000000.0 347000000.0 ... 591000000.0 348000000.0
[1 rows x 10 columns]
最初尝试的问题:IMO更好的数据处理策略是让所需的索引/列在数据处理管道中自然生成或通过标准Pandas API设置,尤其是源数据框中已经存在名称或索引/列时。
编辑:“自然产生所需的索引/列”表示不要在df.f1(...).f2(...).f3(...)...
管道之外进行计算,而将外部生成的索引/列分配给输出DataFrame。一般而言,这种方法可以产生较少的错误且易于维护的代码。
换句话说,手动生成索引或列名不太可能是一种Pandastic的方法,除非可能是为空数据帧进行预分配。
我认为,一次处理多个报价器是一个现实的用例。因此,我也提供了这样一个通用版本,以防万一。当然,该解决方案也适用于单行情数据框。
数据
Report Date Shares Gross Profit
Ticker
AAPL 2010-07-31 347000000.0 543000000.0
AAPL 2010-10-31 344000000.0 548000000.0
AAPL 2011-01-31 347000000.0 556000000.0
AAPL 2011-04-30 347000000.0 580000000.0
AAPL 2011-07-31 348000000.0 591000000.0
GOOG 2011-07-31 448000004.0 691000000.0
GOOG 2010-07-31 447000004.0 643000000.0
GOOG 2010-10-31 444000004.0 648000000.0
GOOG 2011-01-31 447000004.0 656000000.0
GOOG 2011-04-30 447000004.0 680000000.0
代码
df_want = df.reset_index()\
.melt(id_vars=["Ticker", "Report Date"], value_vars=["Shares", "Gross Profit"])\
.sort_values(["Ticker", "Report Date", "variable"])\
.pivot(index="Ticker", columns=["Report Date", "variable"], values="value")
结果
print(df_want)
Report Date 2010-07-31 ... 2011-07-31
variable Gross Profit Shares ... Gross Profit Shares
Ticker ...
AAPL 543000000.0 347000000.0 ... 591000000.0 348000000.0
GOOG 643000000.0 447000004.0 ... 691000000.0 448000004.0
[2 rows x 10 columns]
我在64位debian 10笔记本电脑上使用pandas v1.1.3和python 3.7。