Pandas 行列轉換


Pandas 行列轉換

1.pivot_table

創建一個電子表格風格的數據透視表作為數據幀。

數據透視表中的級別將存儲在結果DataFrame的索引和列上的MultiIndex對象(分層索引)中。

pd.pivot_table(data,  # 制作透視表的數據
               values=None,  # 值
               index=None,  # 行索引
               columns=None,  # 列屬性
               aggfunc='mean',   # 使用的函數,默認是均值
               fill_value=None,  # 缺失值填充
               margins=False, # 是否顯示總計
               dropna=True,   # 缺失值處理
               margins_name='All', # 總計顯示為All
               observed=False,  
               sort=True  # 排序功能  
              )

image-20220119150051418

1.1第一個示例通過求和聚合值

df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
                         "bar", "bar", "bar", "bar"],
                   "B": ["one", "one", "one", "two", "two",
                         "one", "one", "two", "two"],
                   "C": ["small", "large", "large", "small",
                         "small", "large", "small", "small",
                         "large"],
                   "D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
                   "E": [2, 4, 5, 5, 6, 6, 8, 9, 9]})

image-20220119144234175

import numpy as np
table = pd.pivot_table(df, values='D', index=['A', 'B'],
                    columns=['C'], aggfunc=np.sum)
table

image-20220119144335349

1.2可以使用fill_value參數來填充缺失的值。

table = pd.pivot_table(df, values='D', index=['A', 'B'],
                    columns=['C'], aggfunc=np.sum, fill_value=0)
table

image-20220119144534171

1.3下一個示例通過計算多個列的平均值進行聚合。

table = pd.pivot_table(df, values=['D', 'E'], index=['A', 'C'],
                     aggfunc={'D': np.mean,
                              'E': np.mean})
table

image-20220119144646810

1.4計算任意給定值列的多種聚合類型。

table = pd.pivot_table(df, values=['D', 'E'], index=['A', 'C'],
                    aggfunc={'D': np.mean,
                             'E': [min, max, np.mean]})
table

image-20220119144742055

2.cross_tab

計算兩個(或更多)因子的簡單交叉表。默認情況下,除非傳遞值數組和聚合函數,否則計算因子的頻率表。

pandas.crosstab(index, # 行索引,必須是數組結構數據,或者Series,或者是二者的列表形式
                columns, # 列字段;數據要求同上
                values=None,  # 待透視的數據
                rownames=None,  # 行列名字
                colnames=None,  
                aggfunc=None,  # 透視的函數
                margins=False,  # 匯總及名稱設置
                margins_name='All', 
                dropna=True, # 舍棄缺失值
                normalize=False  # 數據歸一化;可以是布爾值、all、index、columns、或者{0,1}
               )

2.1示例

import pandas as pd
df = pd.DataFrame(columns=['date','type','value'])
df['date'] = ['2022-1-{}'.format(i+1) for i in range(3)]*2
df['date'] = pd.to_datetime(df.date)
df['type'] = list('abcaac')
df.value = [2022,1,20,11,11,9]
df

image

cross_tab = pd.crosstab(index=df.date,columns=df.type,values=df.value,aggfunc='mean')
cross_tab

image-20220119151122843

3.gropyby

df.groupby(['date','type'])['value'].mean().unstack()

image-20220119151358373

4.melt

這個函數很有用,可以將DataFrame轉換為一種格式,其中一列或多列是標識符變量(id_vars),而所有其他列,被認為是測量變量(value_vars),被“unpivot”到行軸,只留下兩個非標識符列,‘variable’和‘value’。

pandas.melt(frame, 
            id_vars=None, 
            value_vars=None, 
            var_name=None, 
            value_name='value',
            ignore_index=True,  
            col_level=None)
  • frame:要處理的數據框DataFrame。
  • id_vars:表示不需要被轉換的列名
  • value_vars:表示需要轉換的列名,如果剩下的列全部都需要進行轉換,則不必寫
  • var_name和value_name:自定義設置對應的列名,相當於是取新的列名
  • igonore_index:是否忽略原列名,默認是True,就是忽略了原索引名,重新生成0,1,2,3,4....的自然索引
  • col_level:如果列是多層索引列MultiIndex,則使用此參數;這個參數少用
df3 = pd.melt(df,id_vars='date',value_vars=['type','value'],value_name='observation')
df3

image-20220119151957131

5.wide_to_long

寬面板到長格式。不太靈活,但比melt更方便用戶。

使用 stubnames [‘ a’,‘ b’] ,這個函數期望找到一組或多組格式為 A-suffix1,A-suffix2,... ,B-suffix1,b-suffix2的列,... 您可以使用 j 在結果的長格式中指定要調用這個后綴的內容(例如 j =’year’)

假定這些寬變量的每一行都由 i 惟一標識(可以是單個列名或列名列表)

數據框架中的所有其余變量都保持不變。

wide_to_long(
    df,
    stubnames,
    i,
    j,
    sep: str = "",
    suffix: str = "\\d+"
  • df:待轉換的數據框
  • stubnames:寬表中列名相同的存根部分
  • i:要用作 id 變量的列
  • j:給長格式的“后綴”列設置 columns
  • sep:設置要刪除的分隔符。例如 columns 為 A-2020,則指定 sep='-' 來刪除分隔符。默認為空。
  • suffix:通過設置正則表達式取得“后綴”。默認'\d+'表示取得數字后綴。沒有數字的“后綴”可以用'\D+'來取得

5.1example

np.random.seed(123)
df = pd.DataFrame({"A1970" : {0 : "a", 1 : "b", 2 : "c"},
                   "A1980" : {0 : "d", 1 : "e", 2 : "f"},
                   "B1970" : {0 : 2.5, 1 : 1.2, 2 : .7},
                   "B1980" : {0 : 3.2, 1 : 1.3, 2 : .1},
                   "X"     : dict(zip(range(3), np.random.randn(3)))
                  })
df

image-20220119152851335

df['id'] = df.index
pd.wide_to_long(df, ["A", "B"], i='id', j="year")

image-20220119153147392

5.2也可以有非整數作為后綴。

df = pd.DataFrame({
    'famid': [1, 1, 1, 2, 2, 2, 3, 3, 3],
    'birth': [1, 2, 3, 1, 2, 3, 1, 2, 3],
    'ht_one': [2.8, 2.9, 2.2, 2, 1.8, 1.9, 2.2, 2.3, 2.1],
    'ht_two': [3.4, 3.8, 2.9, 3.2, 2.8, 2.4, 3.3, 3.4, 2.9]
})
df

image-20220119154438700

l = pd.wide_to_long(df, stubnames='ht', i=['famid', 'birth'], j='age',
                    sep='_', suffix=r'\w+')
l

image-20220119154514828

6.explode

explode(column, ignore_index=False)

  • column:待爆炸的元素
  • ignore_index:是否忽略索引;默認是False,保持原來的索引
df = pd.DataFrame({'A': [[0, 1, 2], 'foo', [], [3, 4]],
                   'B': 1,
                   'C': [['a', 'b', 'c'], np.nan, [], ['d', 'e']]})
df

image-20220119154904902

df.explode(list('AC'))

image-20220119160341471

6.1小技巧(將字符串轉換為列表)

df = pd.DataFrame(columns=['name','hobbies'])
df.name = ['peanut','憨憨']
df.hobbies = ['badminton,study','badminton,research']
df

image-20220119163206440

df['hobbies'] = df['hobbies'].apply(lambda x: x.split(','))
df

image-20220119163249436

df.explode('hobbies')

image-20220119163315108

7.transform

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
                          'foo', 'bar'],
                   'B' : ['one', 'one', 'two', 'three',
                          'two', 'two'],
                   'C' : [1, 5, 5, 2, 5, 5],
                   'D' : [2.0, 5., 8., 1., 2., 9.]})

image-20220119164628865

df.groupby('A')['C','D'].transform(lambda x: sum(x))

image-20220119170128376


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM