我有一個看起來像這樣的df1:
年站點 1 2 3 年站點 1 2 3年地點1 2 3年地點 1 2 3
1991 A 4.1 5.9 4。 1 1991 B 3.3 4.1 4. 1 1991 C 4.1 0.6 4. 1 1991 D 4.1 4.1 4.1
1992 A 6.2 5.7 6. 2 1992 B 6.2 7.1 6. 2 1992 C 6.2 6.2 6. 2 1992 D 6.2 9.5 7.4
1993 A 2.6 1.9 4. 7 1993 B 2.6 6.2 2。 6 1993 C 5.4 8.3 2. 6 1993 D 0.4 2.6 2.6
而且,我在將列--是月(1,2,3)--轉置到每個站點的行上時遇到了麻煩,這樣我重新塑造的df1或df2看起來就像這樣:
年 月 站點A 站點B 站點C 站點D
1991 1 4.1 3.3 4.1 4.1
1991 2 5.9 4.1 0.6 4.1
1991 3 4.1 4.1 4.1 4.1
1992 1 6.2 6.2 6.2 6.2
1992 2 5.7 7.1 6.2 9.5
1992 3 6.2 6.2 6.2 7.4
1993 1 2.6 2.6 5.4 0.4
1993 2 1.9 6.2 8.3 2.6
1993 3 4.7 2.6 2.6 2.6
我已經嘗試使用'melt'和'stack',但我不明白如何參考重復的月份(1、2、3)。謝謝你,
uj5u.com熱心網友回復:
我們可以創建一個新的級別的列,通過它,每一個列的標題都是用groupby cumcount進行位置分組。這樣做的好處是,只要列的名稱相同,就不需要按固定的順序排列。
然后使用stack來獲取所有獨立的組到行中,set_index來排除網站和年份列,然后stack和unstack以站點而不是月份進行分組:
# calculate new MultiIndex level.
midx = pd.MultiIndex.from_arrays([
df.columns,
df.columns.to_series().groupby(level=0).comcount()
])
new_df = (
df.set_axis(midx, axis=1) # replace columns
.stack() # 將所有組移至行中。
.set_index(['site', 'year']) #保存site和year。
.rename_axis(columns='Month') # 重命名列軸為Month。
.stack() # 將所有月份列移至行。
.unstack(site') # 將site的行轉換為列。
.add_prefix('site ') # 添加前綴。
.rename_axis(columns=None) # 洗掉軸名。
.reset_index() # 恢復范圍內的索引。
)
new_df:
年 月 網站A 網站B 網站C 網站D
0 1991 1 A1 B1 C1 D1
1 1991 2 A2 B2 C2 D2
2 1991 3 A3 B3 C3 D3
3 1992 1 A1 B1 C1 D1
4 1992 2 A2 B2 C2 D2
5 1992 3 A3 B3 C3 D3
6 1993 1 A1 B1 C1 D1
7 1993 2 A2 B2 C2 D2
8 1993 3 A3 B3 C3 D3
更冒險的方法是reshape DataFrame.values基于設定的唯一列數(5),然后剩下的就和上面一樣了:
unique_cols = df.columns.unique() .tolist()
new_df = (
pd.DataFrame(
# reshape dataframe into len(unique_cols) columns。
#和多少行。
df.values.reshape((-1, len(unique_cols))。
columns=unique_cols # 恢復列名。
).set_index(['year', 'site'] )
.rename_axis(columns='Month') # 重命名列軸為Month。
.stack() # 將所有月份列移至行。
.unstack(site') # 將site的行轉換為列。
.add_prefix('site ') # 添加前綴。
.rename_axis(columns=None) # 洗掉軸名。
.reset_index() # 恢復范圍內的索引。
)
new_df:
年 月 網站A 網站B 網站C 網站D
0 1991 1 A1 B1 C1 D1
1 1991 2 A2 B2 C2 D2
2 1991 3 A3 B3 C3 D3
3 1992 1 A1 B1 C1 D1
4 1992 2 A2 B2 C2 D2
5 1992 3 A3 B3 C3 D3
6 1993 1 A1 B1 C1 D1
7 1993 2 A2 B2 C2 D2
8 1993 3 A3 B3 C3 D3
*注意這種方法只有在DataFrame結構可以被保證的情況下才有效,因為我們通過用numpy重構繞過了所有pandas資料完整性檢查。
使用的設定:
from itertools import chain
import pandas as pd
sites = "ABCD"/span>
df = pd.DataFrame(
chain.from_iterable([range(1991,1994),
[f'{v}'/span>] * 3,
[f'{v}'] * 3,
[f'{v}2'] * 3,
[f'{v}3'] * 3] for v in sites)
).T
df.columns = ['year', 'site', 1, 2, 3] * len(site)
簡略的df:
年站點1 2 3年站點1 ... 1 2 3年站點 1 2 3
0 1991 A A1 A2 A3 1991 B B1 ... C1 C2 C3 1991 D D1 D2 D3
1 1992 A A1 A2 A3 1992 B B1 ... C1 C2 C3 1992 D D1 D2 D3
2 1993 A A1 A2 A3 1993 B B1 ... C1 C2 C3 1993 D D1 D2 D3
uj5u.com熱心網友回復:
嘗試使用硬索引切片和重塑的方法:
#Create input dataframe
np.random.seed(0)
df = pd.concat([pd.DataFrame({'year':[1991, 1992, 1993] 。
'site': [i]*3,
1:np.round(np.random. randint(2,8,3) np.random.random(3),1)。
2:np.round(np.random. randint(2,8,3) np.random.random(3),1)。)
3:np.round(np.random. randint(2,8,3) np.random.random(3) ,1) }) for i in [*'ABC'/span>]], axis=1)
#索引資料框架的分片列5] for i in range(0, df. shape[1],5) ])
# 用melt、set_index和unstack重塑。
df_out = df_out.melt(['year', 'site'], var_name='month')
.set_index(['year', 'month', 'site']) ['value']
.unstack('site').add_prefix('Site')
.reset_index()
print(df_out)
輸出:
site year month Site A Site B Site C
0 1991 1 6.6 6.0 5.5
1 1991 2 7.3 5.5 7.6
2 1991 3 3.9 2.5 4.7
3 1992 1 7.5 2.1 5.6
4 19922 4.1 2.8 7.9
5 1992 3 2.1 3.8 2.1
6 19931 2.4 5.9 4.0
7 1993 2 6.3 3.1 2.7
8 1993 3 3.1 3.1 3.7
uj5u.com熱心網友回復:
@HenryEcker的解決方案是正確的,也是首選的,特別是當列的結構不像上面的那樣時,
。下面的解決方案使用pivot_longer,來自pyjanitor,并假設列的順序(如果你不確定順序,@HenryEcker的解決方案是安全的,并能完成作業,并有獨特的想法):
# use Henry's data
# pip install pyjanitor
import janitor
import pandas as pd
df = df.rename(columns = str)
unique_columns = [*df.columns.unique()
(df.pivot_longer(names_to = unique_columns),
names_pattern = unique_columns)
.pivot('year', 'site')
.stack(level = 0)
.add_prefix('Site')
.rename_axis(columns = None,
index = ['year', 'month'])
.reset_index()
)
年份 月 份 SiteA SiteB SiteC SiteD
0 1991 1 A1 B1 C1 D1
1 1991 2 A2 B2 C2 D2
2 1991 3 A3 B3 C3 D3
3 1992 1 A1 B1 C1 D1
4 1992 2 A2 B2 C2 D2
5 1992 3 A3 B3 C3 D3
6 1993 1 A1 B1 C1 D1
7 1993 2 A2 B2 C2 D2
8 1993 3 A3 B3 C3 D3
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/321116.html
標籤:
上一篇:如何讀取一個陣列并回傳一個陣列?
