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