単純なデータフレームがある場合:
print(a)
one two three
0 A 1 a
1 A 2 b
2 B 1 c
3 B 2 d
4 C 1 e
5 C 2 f
次のコマンドを発行して、行にマルチインデックスを簡単に作成できます。
a.set_index(['one', 'two'])
three
one two
A 1 a
2 b
B 1 c
2 d
C 1 e
2 f
列にマルチインデックスを作成する同様に簡単な方法はありますか?
私は終わりにしたいと思います:
one A B C
two 1 2 1 2 1 2
0 a b c d e f
この場合、行のマルチインデックスを作成して転置するのは非常に簡単ですが、他の例では、行と列の両方にマルチインデックスを作成する必要があります。
pivot_table
に続いて、データフレームに一連の操作を行い、目的のフォームを取得します。
df_pivot = pd.pivot_table(df, index=['one', 'two'], values='three', aggfunc=np.sum)
def rename_duplicates(old_list): # Replace duplicates in the index with an empty string
seen = {}
for x in old_list:
if x in seen:
seen[x] += 1
yield " "
else:
seen[x] = 0
yield x
col_group = df_pivot.unstack().stack().reset_index(level=-1)
col_group.index = rename_duplicates(col_group.index.tolist())
col_group.index.name = df_pivot.index.names[0]
col_group.T
one A B C
two 1 2 1 2 1 2
0 a b c d e f
短い答えは[〜#〜] no [〜#〜]だと思います。マルチインデックス列を使用するには、データフレームにヘッダーに変換する2つ(またはそれ以上)の行が必要です(マルチインデックス行の列のように)。この種のデータフレームがある場合、マルチインデックスヘッダーの作成はそれほど難しくありません。これは非常に長いコード行で行うことができ、他の任意のデータフレームで再利用できます。異なる場合は、ヘッダーの行番号のみを考慮して変更する必要があります。
df = pd.DataFrame({'a':['foo_0', 'bar_0', 1, 2, 3], 'b':['foo_0', 'bar_1', 11, 12, 13],
'c':['foo_1', 'bar_0', 21, 22, 23], 'd':['foo_1', 'bar_1', 31, 32, 33]})
データフレーム:
a b c d
0 foo_0 foo_0 foo_1 foo_1
1 bar_0 bar_1 bar_0 bar_1
2 1 11 21 31
3 2 12 22 32
4 3 13 23 33
マルチインデックスオブジェクトの作成:
arrays = [df.iloc[0].tolist(), df.iloc[1].tolist()]
tuples = list(Zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df.columns = index
マルチインデックスヘッダーの結果:
first foo_0 foo_1
second bar_0 bar_1 bar_0 bar_1
0 foo_0 foo_0 foo_1 foo_1
1 bar_0 bar_1 bar_0 bar_1
2 1 11 21 31
3 2 12 22 32
4 3 13 23 33
最後に、0〜1行を削除してから、行インデックスをリセットする必要があります。
df = df.iloc[2:].reset_index(drop=True)
「1行」バージョン(変更する必要があるのは、ヘッダーインデックスとデータフレーム自体を指定することだけです):
idx_first_header = 0
idx_second_header = 1
df.columns = pd.MultiIndex.from_tuples(list(Zip(*[df.iloc[idx_first_header].tolist(),
df.iloc[idx_second_header].tolist()])), names=['first', 'second'])
df = df.drop([idx_first_header, idx_second_header], axis=0).reset_index(drop=True)