我有一個示例資料框 df,我想在其中維護原始資料集中的所有列,并根據現有資料集創建一個新的透視列。(按 id 分組)原始資料框大約有 80 列
資料
s1 s2 id q122c q122a q122c2 q122a2 q222c q222a q222c2 q222a2 q322c q322a q322c2 q322a2
50 1000 aa 40 10 900 100 50 0 1000 0 60 -10 1100 -100
100 2000 bb 50 50 1500 500 75 25 1900 100 100 0 2000 0
想要的
s1 s2 id date consumed1 avail1 consumed2 avail2
50 1000 aa q122 40 10 900 100
50 1000 aa q222 50 0 1000 0
50 1000 aa q322 60 -10 1100 -100
100 2000 bb q122 50 50 1500 500
100 2000 bb q222 75 25 1900 100
100 2000 bb q322 100 0 2000 0
正在做
pd.wide_to_long(df.set_index(['stat1','stat2','id']).stack().groupby(level=[0,1,2,3]).agg(list).apply(pd.Series).unstack().stack(level=0).reset_index(),
stubnames = ['q122','q222'], i = ['stat1','stat2','id','level_3'],j = 'date',suffix='\\w ').stack().unstack(level=[-3,-2])
SO 成員提供了一個腳本,可以將資料從寬到長,但是,我得到的輸出并未捕獲所需的所有列。
任何建議表示贊賞。
uj5u.com熱心網友回復:
有幾種方法可以解決這個問題:
一種選擇是將列轉換為 MultiIndex,然后使用堆疊重塑:
index = ['s1', 's2', 'id']
temp = df.set_index(index)
temp.columns = temp.columns.str.split(r"([a|c]\d?)", expand = True).droplevel(-1)
temp.columns.names = ['date', None]
(temp.stack(level='date')
.rename(columns={'c':'consumed1',
'a':'avail1',
'c2':'consumed2',
'a2':'avail2'})
.reset_index()
)
s1 s2 id date avail1 avail2 consumed1 consumed2
0 50 1000 aa q122 10 100 40 900
1 50 1000 aa q222 0 0 50 1000
2 50 1000 aa q322 -10 -100 60 1100
3 100 2000 bb q122 50 500 50 1500
4 100 2000 bb q222 25 100 75 1900
5 100 2000 bb q322 0 0 100 2000
與pd.wide_to_long:
index = ['s1', 's2', 'id']
temp = df.set_index(index)
temp.columns = temp.columns.str.split(r"([a|c]\d?)").str[::-1].str[1:].str.join('_')
(pd.wide_to_long(temp.reset_index(),
stubnames = ['c', 'a', 'c2', 'a2'],
i = index,
j = 'date',
sep='_',
suffix='. ')
.rename(columns={'c':'consumed1',
'a':'avail1',
'c2':'consumed2',
'a2':'avail2'})
.reset_index()
)
s1 s2 id date consumed1 avail1 consumed2 avail2
0 50 1000 aa q122 40 10 900 100
1 50 1000 aa q222 50 0 1000 0
2 50 1000 aa q322 60 -10 1100 -100
3 100 2000 bb q122 50 50 1500 500
4 100 2000 bb q222 75 25 1900 100
5 100 2000 bb q322 100 0 2000 0
另一種選擇是 pivot_longerfrom pyjanitor,它為這種復雜的重塑提供了一種更簡單的方法:
#pip install pyjanitor
import pandas as pd
import janitor
(df.pivot_longer(slice('s1', 'id'),
names_to = ('date', '.value'),
names_pattern = r"([a-z]\d )(. )",
sort_by_appearance=True)
.rename(columns={'c':'consumed1',
'a':'avail1',
'c2':'consumed2',
'a2':'avail2'})
)
s1 s2 id date consumed1 avail1 consumed2 avail2
0 50 1000 aa q122 40 10 900 100
1 50 1000 aa q222 50 0 1000 0
2 50 1000 aa q322 60 -10 1100 -100
3 100 2000 bb q122 50 50 1500 500
4 100 2000 bb q222 75 25 1900 100
5 100 2000 bb q322 100 0 2000 0
在names_pattern指明列將如何重塑。有兩個值names_to:('date', '.value')。中還有兩個正則運算式組names_pattern。第一個正則運算式組將配對date以形成新列,而第二個正則運算式組將配對.value以形成新標題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/376359.html
上一篇:如何將坐標陣列排序為列坐標組?
下一篇:使用SciPy計算分箱均值??:binned_statistic 處理NaN(SciPy的ValueError和statistic=np.nanmean)
