以下に示すように、ピボットテーブルから派生したPandas DataFrameを行表現に変換したいと思います。
これは私がいるところです:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'goods': ['a', 'a', 'b', 'b', 'b'],
'stock': [5, 10, 30, 40, 10],
'category': ['c1', 'c2', 'c1', 'c2', 'c1'],
'date': pd.to_datetime(['2014-01-01', '2014-02-01', '2014-01-06', '2014-02-09', '2014-03-09'])
})
# we don't care about year in this example
df['month'] = df['date'].map(lambda x: x.month)
piv = df.pivot_table(["stock"], "month", ["goods", "category"], aggfunc="sum")
piv = piv.reindex(np.arange(piv.index[0], piv.index[-1] + 1))
piv = piv.ffill(axis=0)
piv = piv.fillna(0)
print piv
その結果
stock
goods a b
category c1 c2 c1 c2
month
1 5 0 30 0
2 5 10 30 40
3 5 10 10 40
そして、これは私が行きたい場所です。
goods category month stock
a c1 1 5
a c1 2 0
a c1 3 0
a c2 1 0
a c2 2 10
a c2 3 0
b c1 1 30
b c1 2 0
b c1 3 10
b c2 1 0
b c2 2 40
b c2 3 0
以前は 、使用しました
piv = piv.stack()
piv = piv.reset_index()
print piv
マルチインデックスを取り除くためにこれを行いますが、2つの列(["goods", "category"]
):
month category stock
goods a b
0 1 c1 5 30
1 1 c2 0 0
2 2 c1 5 30
3 2 c2 10 40
4 3 c1 5 10
5 3 c2 10 40
列のマルチインデックスを取り除き、結果を例示された形式のDataFrameに取得する方法を誰かが知っていますか?
>>> piv.unstack().reset_index().drop('level_0', axis=1)
goods category month 0
0 a c1 1 5
1 a c1 2 5
2 a c1 3 5
3 a c2 1 0
4 a c2 2 10
5 a c2 3 10
6 b c1 1 30
7 b c1 2 30
8 b c1 3 10
9 b c2 1 0
10 b c2 2 40
11 b c2 3 40
次に、最後の列名を0
からstock
に変更するだけです。
melt
(aka unpivot) はあなたがやりたいことに非常に近いようです:
In [11]: pd.melt(piv)
Out[11]:
NaN goods category value
0 stock a c1 5
1 stock a c1 5
2 stock a c1 5
3 stock a c2 0
4 stock a c2 10
5 stock a c2 10
6 stock b c1 30
7 stock b c1 30
8 stock b c1 10
9 stock b c2 0
10 stock b c2 40
11 stock b c2 40
不正な列(株式)があり、列ヘッダーがpivで一定であることがここに表示されます。最初にドロップすると、メルトはOOTBで機能します。
In [12]: piv.columns = piv.columns.droplevel(0)
In [13]: pd.melt(piv)
Out[13]:
goods category value
0 a c1 5
1 a c1 5
2 a c1 5
3 a c2 0
4 a c2 10
5 a c2 10
6 b c1 30
7 b c1 30
8 b c1 10
9 b c2 0
10 b c2 40
11 b c2 40
編集:上記は実際にインデックスを削除します。reset_index
で列にする必要があります:
In [21]: pd.melt(piv.reset_index(), id_vars=['month'], value_name='stock')
Out[21]:
month goods category stock
0 1 a c1 5
1 2 a c1 5
2 3 a c1 5
3 1 a c2 0
4 2 a c2 10
5 3 a c2 10
6 1 b c1 30
7 2 b c1 30
8 3 b c1 10
9 1 b c2 0
10 2 b c2 40
11 3 b c2 40
質問にはすでに回答済みですが、データセットのマルチインデックス列の問題では、提供されたソリューションは非効率的でした。そこで、ここではパンダを使用してマルチインデックス列のピボットを解除する別のソリューションを投稿しています。
これが私が抱えていた問題です:
ご覧のとおり、データフレームは3つのマルチインデックスと2つのレベルのマルチインデックス列で構成されています。
必要なデータフレーム形式は次のとおりです。
上記のオプションを試したところ、pd.melt関数ではvar_name属性に複数の列を含めることができませんでした。したがって、メルトを試すたびに、テーブルから一部の属性が失われることになります。
私が見つけた解決策は、私のデータフレームにダブルスタッキング関数を適用することでした。
コーディングの前に、ピボットされていないテーブル列に必要なvar_nameが「Populacao residente em domicilios specifices ocupados」であったことに注目してください(以下のコードを参照)。したがって、私のすべての値エントリについては、これらを新しく作成されたvar_name新しい列にスタックする必要があります。
以下がスニペットコードです。
import pandas as pd
# reading my table
df = pd.read_Excel(r'my_table.xls', sep=',', header=[2,3], encoding='latin3',
index_col=[0,1,2], na_values=['-', ' ', '*'], squeeze=True).fillna(0)
df.index.names = ['COD_MUNIC_7', 'NOME_MUN', 'TIPO']
df.columns.names = ['sexo', 'faixa_etaria']
df.head()
# making the stacking:
df = pd.DataFrame(pd.Series(df.stack(level=0).stack(), name='Populacao residente em domicilios particulares ocupados')).reset_index()
df.head()
私が見つけた別の解決策は、最初にデータフレームにスタッキング関数を適用し、次にメルトを適用することでした。
ここに代替コードがあります:
df = df.stack('faixa_etaria').reset_index().melt(id_vars=['COD_MUNIC_7', 'NOME_MUN','TIPO', 'faixa_etaria'],
value_vars=['Homens', 'Mulheres'],
value_name='Populacao residente em domicilios particulares ocupados',
var_name='sexo')
df.head()
敬具、
フィリップリスキッラリール