來源:How do I flatten a python/pandas pivot table and manipulate the column names?鏈接這裏。
問題:把一般情況下得到的透視表,變成想要的格式:
"""一般情況下,透視表如下:"""
df = pd.pivot_table(DataFrame,
values=['BUCKET'],
index=['ID'],
columns=['TYPE'],
aggfunc=len)
print(df)
# 運行結果如下:
BUCKET
TYPE B1 B2 B3 B4
ID
1 236 data1 data2 data3
2 323 data4 data5 data3
3 442 data6 data2 data4
4 543 data8 data2 data3
5 676 data1 data8 data4
"""
問題是,我想要如下所示的格式:
ID B1 B2 B3 B4
1 236 data1 data2 data3
2 323 data4 data5 data3
3 442 data6 data2 data4
4 543 data8 data2 data3
5 676 data1 data8 data4
"""
第一種解決方法:
先去除透視表的行名稱,最後重置透視表的index。
- 第1/3步: pandas.DataFrame.droplevel把“BUCKET”刪除:
df.columns = df.columns.droplevel(0)
print(df)
# 結果如下
TYPE B1 B2 B3 B4
ID
1 236 data1 data2 data3
2 323 data4 data5 data3
3 442 data6 data2 data4
4 543 data8 data2 data3
5 676 data1 data8 data4
- 第2/3步:使用 pandas.DataFrame.rename_axis去除columns列的名稱
df_1 = df.rename_axis([None], axis=1) # columns有N個,就用N個None
print(df_1) # 本初的“TYPE”被重置爲空;但是 ID 和 B1,B2,B3,B4不在一行
# 結果如下
B1 B2 B3 B4
ID
1 236 data1 data2 data3
2 323 data4 data5 data3
3 442 data6 data2 data4
4 543 data8 data2 data3
5 676 data1 data8 data4
- 第3/3步:pandas.DataFrame.reset_index重置index
df_2 = df.rename_axis(None, axis=1).reset_index()
print(df_2)
# 結果如下
ID B1 B2 B3 B4
0 1 236 data1 data2 data3
1 2 323 data4 data5 data3
2 3 442 data6 data2 data4
3 4 543 data8 data2 data3
4 5 676 data1 data8 data4
#注:如果改爲df_2 = df.rename_axis(None, axis=1).reset_index(drop=True) ,則由pandas默認值取代原來的index,即'ID’被刪除。
第二種解決方法:直接保存爲csv格式,然後讀取。
df.columns = df.columns.droplevel(0)
df.to_csv('文件路徑+文件名.csv', encoding='utf-8-sig', index=False)
打開儲存的文件可以看到:
ID | B1 | B2 | B3 | B4 |
---|---|---|---|---|
1 | 236 | data1 | data2 | data3 |
2 | 323 | data4 | data5 | data3 |
3 | 442 | data6 | data2 | data4 |
4 | 543 | data8 | data2 | data3 |
5 | 676 | data1 | data8 | data4 |
pandas讀取 ‘文件路徑+文件名.csv’ 後,結果是
df_new = pd.read_csv('文件路徑+文件名.csv')
print(df_new)
ID B1 B2 B3 B4
0 1 236 data1 data2 data3
1 2 323 data4 data5 data3
2 3 442 data6 data2 data4
3 4 543 data8 data2 data3
4 5 676 data1 data8 data4
附註:在df_new
的基礎上,用pandas.DataFrame.set_index把ID
作爲index列,不能得到:
ID B1 B2 B3 B4
1 236 data1 data2 data3
2 323 data4 data5 data3
3 442 data6 data2 data4
4 543 data8 data2 data3
5 676 data1 data8 data4
得到的而是:
df_new.set_index('ID', inplace=True)
print(df_new)
# 結果如下
B1 B2 B3 B4
ID
1 236 data1 data2 data3
2 323 data4 data5 data3
3 442 data6 data2 data4
4 543 data8 data2 data3
5 676 data1 data8 data4