python--pandas長寬數(shù)據(jù)變形

長型數(shù)據(jù)(long format dataframe)與寬型數(shù)據(jù)(wide format dataframe)是兩種形式的數(shù)據(jù)框吆玖,在數(shù)據(jù)分析中高頻出現(xiàn)筒溃,在數(shù)據(jù)處理過程中,
常常需要在兩者之間相互轉(zhuǎn)換沾乘。本文基于pandas怜奖,介紹長型數(shù)據(jù)與寬型數(shù)據(jù)的相互轉(zhuǎn)換操作。

環(huán)境

  • python3.9
  • win10 64bit
  • pandas==1.2.1

寬轉(zhuǎn)長

在pandas中翅阵,寬型轉(zhuǎn)長型數(shù)據(jù)有meltwide_to_long兩種方法歪玲。

melt

melt方法叫做數(shù)據(jù)融合,是dataFrame擁有的方法掷匠,使用較為頻繁滥崩。參數(shù)解釋如下:

DataFrame.melt(id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None, ignore_index=True)

  • id_vars:[tuple, list, ndarray],列中識別符變量槐雾,不參與融合夭委。
  • value_vars:[tuple, list, ndarray],列中融合變量募强,默認全部融合株灸。
  • var_name:[scalar],融合后變量名字擎值,默認variable慌烧。
  • value_name:[scalar],融合后值名字鸠儿,默認value屹蚊。
  • col_level:[int, str],多重列索引時選擇列进每。
  • ignore_index:[bool]汹粤,融合后索引是否重新排序,默認True田晚。
import pandas as pd
pd.set_option('display.notebook_repr_html',False)
# 寬型數(shù)據(jù)
w_df = pd.DataFrame({'A': [1,2,3],
                   'B': [4,5,6],
                   'C': [7,8,9]})
w_df
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9
  • 當不傳入任何參數(shù)時嘱兼,默認會融合全部的列。
# 全部融合
w_df.melt()
  variable  value
0        A      1
1        A      2
2        A      3
3        B      4
4        B      5
5        B      6
6        C      7
7        C      8
8        C      9
  • 設(shè)置id_vars參數(shù)贤徒,選擇部分列作為識別符不參與融合芹壕,剩余的列將全部融合。
# A標識接奈,B踢涌,C融合
w_df.melt(id_vars=['A'])
   A variable  value
0  1        B      4
1  2        B      5
2  3        B      6
3  1        C      7
4  2        C      8
5  3        C      9
# A,B標識序宦,C融合
w_df.melt(id_vars=['A','B'])
   A  B variable  value
0  1  4        C      7
1  2  5        C      8
2  3  6        C      9
  • 設(shè)置value_vars參數(shù)睁壁,選擇部分列作為融合列。

注意剩余的列不會自動作為標識符列。

# 只融合A
w_df.melt(value_vars=['A'])
  variable  value
0        A      1
1        A      2
2        A      3
# 只融合A,B
w_df.melt(value_vars=['A','B'])
  variable  value
0        A      1
1        A      2
2        A      3
3        B      4
4        B      5
5        B      6
  • 設(shè)置var_name(默認variable),value_name(默認value)參數(shù)潘明,為融合的變量與值設(shè)置名字糠惫。
# 設(shè)置融合后變量名與值名
w_df.melt(var_name='code',value_name='count')
  code  count
0    A      1
1    A      2
2    A      3
3    B      4
4    B      5
5    B      6
6    C      7
7    C      8
8    C      9
  • 設(shè)置ignore_index=False可以保留原數(shù)據(jù)的索引。
w_df.melt(ignore_index=False)
  variable  value
0        A      1
1        A      2
2        A      3
0        B      4
1        B      5
2        B      6
0        C      7
1        C      8
2        C      9
  • 設(shè)置col_level參數(shù)钉疫,可以選擇多重列索引數(shù)據(jù)來融合數(shù)據(jù)硼讽。
# 列多重索引數(shù)據(jù)
mi_w_df=w_df.copy()
mi_w_df.columns=[list('ABC'),list('DEF')]
mi_w_df
   A  B  C
   D  E  F
0  1  4  7
1  2  5  8
2  3  6  9
# 融合第一索引列
mi_w_df.melt(col_level=0)
  variable  value
0        A      1
1        A      2
2        A      3
3        B      4
4        B      5
5        B      6
6        C      7
7        C      8
8        C      9
# 融合第二索引列
mi_w_df.melt(col_level=1)
  variable  value
0        D      1
1        D      2
2        D      3
3        E      4
4        E      5
5        E      6
6        F      7
7        F      8
8        F      9

wide_to_long

wide_to_long函數(shù)是pandas自帶的,是對melt的一種補充牲阁,在特殊的寬轉(zhuǎn)長情況下更適用固阁。

pandas.wide_to_long(df, stubnames, i, j, sep='', suffix='\d+')

  • df:[pd.dataframe],寬型數(shù)據(jù)框
  • stubnames:[str,list-like]城菊,列名中的存根名字
  • i:[str,list-like]备燃,列中的索引變量
  • j:[str],后綴的重命名
  • sep:[str,default ""]凌唬,存根名與后綴之間的分隔符
  • suffix:[str,default "\d+"]并齐,后綴
# 寬型數(shù)據(jù)
s_df = pd.DataFrame({"A1970" : [1,33,3],
                   "B1980" : [3,5,7],
                   "A1980" : [13,15,17],
                   "B1970" : [6,8,14],
                   "x"     : [1,2,3],
                   "y"     : [4,5,6]})
s_df
   A1970  B1980  A1980  B1970  x  y
0      1      3     13      6  1  4
1     33      5     15      8  2  5
2      3      7     17     14  3  6

在數(shù)據(jù)中,A1970,B1980,A1980,B1970這幾列名字具有相同的結(jié)構(gòu)客税,如果需要將它們分開况褪,就可以用long_to_wide函數(shù)。

# 特定列的寬轉(zhuǎn)長
pd.wide_to_long(s_df,stubnames=['A','B'],j='year',i='x')
        y   A   B
x year           
1 1970  4   1   6
  1980  4  13   3
2 1970  5  33   8
  1980  5  15   5
3 1970  6   3  14
  1980  6  17   7
  • 設(shè)置stubnames更耻,函數(shù)會根據(jù)設(shè)置的字符去數(shù)據(jù)列中匹配目標列测垛,然后轉(zhuǎn)換為長數(shù)據(jù)
# 只轉(zhuǎn)換包含A的列
pd.wide_to_long(s_df,stubnames=['A',],j='year',i='x')
        B1970  y  B1980   A
x year                     
1 1970      6  4      3   1
2 1970      8  5      5  33
3 1970     14  6      7   3
1 1980      6  4      3  13
2 1980      8  5      5  15
3 1980     14  6      7  17

如果stubnames參數(shù)設(shè)置的字符在原數(shù)據(jù)框的列中無法找到,則返回空數(shù)據(jù)框秧均。

# 列名中不存在C字符食侮,返回空數(shù)據(jù)框
pd.wide_to_long(s_df,stubnames=['C',],j='year',i='x')
Empty DataFrame
Columns: [B1970, y, A1980, B1980, A1970, C]
Index: []
  • 參數(shù)i可以設(shè)置為多列,返回多個索引目胡。
# 設(shè)置多索引
pd.wide_to_long(s_df,stubnames=['A','B'],j='year',i=['x','y'])
           A   B
x y year        
1 4 1970   1   6
    1980  13   3
2 5 1970  33   8
    1980  15   5
3 6 1970   3  14
    1980  17   7
  • 參數(shù)sep表示分隔符锯七,默認"",可以根據(jù)實際情況設(shè)置誉己。
# 寬型數(shù)據(jù)(-分隔符)
sep_df = pd.DataFrame({"A-1970" : [1,33,3],
                   "B-1980" : [3,5,7],
                   "A-1980" : [13,15,17],
                   "B-1970" : [6,8,14],
                   "x"     : [1,2,3],
                   "y"     : [4,5,6]})
sep_df
   A-1970  B-1980  A-1980  B-1970  x  y
0       1       3      13       6  1  4
1      33       5      15       8  2  5
2       3       7      17      14  3  6

數(shù)據(jù)中列名的分隔符為-眉尸,則轉(zhuǎn)換的時候需要設(shè)置sep='-'

# 設(shè)置sep參數(shù)
pd.wide_to_long(sep_df,stubnames=['A','B'],j='year',i='x',sep='-')
        y   A   B
x year           
1 1970  4   1   6
  1980  4  13   3
2 1970  5  33   8
  1980  5  15   5
3 1970  6   3  14
  1980  6  17   7
  • 參數(shù)suffix表示后綴巫延,默認是"\d+"效五,是正則表達式地消,表示匹配數(shù)字炉峰,可以根據(jù)實際情況替換。
# 寬型數(shù)據(jù)
suf_df = pd.DataFrame({"Aone" : [1,33,3],
                   "Btwo" : [3,5,7],
                   "Atwo" : [13,15,17],
                   "Bone" : [6,8,14],
                   "x"     : [1,2,3],
                   "y"     : [4,5,6]})
suf_df
   Aone  Btwo  Atwo  Bone  x  y
0     1     3    13     6  1  4
1    33     5    15     8  2  5
2     3     7    17    14  3  6
# 指定后綴
pd.wide_to_long(suf_df,stubnames=['A','B'],j='year',i='x',suffix='(one|two)')
        y   A   B
x year           
1 one   4   1   6
  two   4  13   3
2 one   5  33   8
  two   5  15   5
3 one   6   3  14
  two   6  17   7

長轉(zhuǎn)寬

長型數(shù)據(jù)轉(zhuǎn)為寬型數(shù)據(jù)可以通過透視的功能實現(xiàn)脉执,類似于excel中的透視表功能疼阔。在pandas中用pivot方法實現(xiàn)。

DataFrame.pivot(index=None, columns=None, values=None)

  • index:[str ,object ,a list of str],透視的索引
  • columns:[str ,object ,a list of str]婆廊,透視的列
  • values:[str, object ,a list of the previous]迅细,透視的值
# 長型數(shù)據(jù)
l_df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two','two'],
                   'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'cat':['alpha','alpha','alpha','beta','beta','beta'],
                   'baz': [1, 2, 3, 4, 5, 6],
                   'zoo': [4, 6, 8, 1, 2, 9]})
l_df
   foo bar    cat  baz  zoo
0  one   A  alpha    1    4
1  one   B  alpha    2    6
2  one   C  alpha    3    8
3  two   A   beta    4    1
4  two   B   beta    5    2
5  two   C   beta    6    9

選擇foo列作為透視后的索引,bar列作為透視的列淘邻,里面的元素會展開成新數(shù)據(jù)框的列茵典,baz作為透視的值,填充在新數(shù)據(jù)框中宾舅。

# 透視數(shù)據(jù)
l_df.pivot(index='foo',columns='bar',values='baz')
bar  A  B  C
foo         
one  1  2  3
two  4  5  6
  • 設(shè)置index為多個列名统阿,透視表將具有多個行索引。
# 多索引透視
l_df.pivot(index=['foo','bar'],columns='cat',values='baz')
cat      alpha  beta
foo bar             
one A      1.0   NaN
    B      2.0   NaN
    C      3.0   NaN
two A      NaN   4.0
    B      NaN   5.0
    C      NaN   6.0
  • 設(shè)置columns為多個列名筹我,透視表將具有多個列索引扶平。
# 多列透視
l_df.pivot(index='foo',columns=['bar','cat'],values='baz')
bar     A     B     C    A    B    C
cat alpha alpha alpha beta beta beta
foo                                 
one   1.0   2.0   3.0  NaN  NaN  NaN
two   NaN   NaN   NaN  4.0  5.0  6.0
  • 設(shè)置values為多個列名。
l_df.pivot(index='foo',columns='bar',values=['baz','zoo'])

    baz       zoo      
bar   A  B  C   A  B  C
foo                    
one   1  2  3   4  6  8
two   4  5  6   1  2  9
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔬蕊,一起剝皮案震驚了整個濱河市结澄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岸夯,老刑警劉巖麻献,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異猜扮,居然都是意外死亡赎瑰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門破镰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來餐曼,“玉大人,你說我怎么就攤上這事鲜漩≡雌” “怎么了?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵孕似,是天一觀的道長踩娘。 經(jīng)常有香客問我,道長喉祭,這世上最難降的妖魔是什么养渴? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上赘理,老公的妹妹穿的比我還像新娘芜果。我一直安慰自己,他們只是感情好藐唠,可當我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布帆疟。 她就那樣靜靜地躺著,像睡著了一般宇立。 火紅的嫁衣襯著肌膚如雪踪宠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天妈嘹,我揣著相機與錄音柳琢,去河邊找鬼。 笑死润脸,一個胖子當著我的面吹牛染厅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播津函,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼肖粮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了尔苦?” 一聲冷哼從身側(cè)響起涩馆,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎允坚,沒想到半個月后魂那,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡稠项,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年涯雅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片展运。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡活逆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拗胜,到底是詐尸還是另有隱情蔗候,我是刑警寧澤,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布埂软,位于F島的核電站锈遥,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏勘畔。R本人自食惡果不足惜所灸,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炫七。 院中可真熱鬧爬立,春花似錦、人聲如沸诉字。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壤圃。三九已至陵霉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伍绳,已是汗流浹背踊挠。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留冲杀,地道東北人效床。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像权谁,于是被迫代替她去往敵國和親剩檀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內(nèi)容