金融量化学习---Python, MySQL, Pandas

这里用来记录一些在金融领域,尤其是银行相关的资金、债券、票据中应用到的数据管理与分析, 编程等心得或笔记,以及个人的一点小小兴趣(易经八卦、藏密禅修)等

导航

MultiIndex 层次化索引(hierarchical indexing)

层次化索引

层次化索引:(hierarchical indexing)在一个轴上拥有多个(两个以上)索引级别,使用户能以低维度形式处理高维度数据。

levels:每个等级上轴标签的唯一值
labels:以整数来表示每个level上标签的位置
sortorder:按照指定level上的标签名称的字典顺序进行排序(可选参数)
names:index level的名称
copy:布尔值,默认为False。是否拷贝元数据产生新的对象
verify_integrity:布尔值,默认为Ture。检查levels/labels是否持续有效

入门级demo学习

import pandas as pd
import numpy as np
data = pd.Series(np.random.randn(10),
              index=[['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'd', 'd'],
                     [1, 2, 3, 1, 2, 3, 1, 2, 2, 3]])
print("----------print data---------------")
print(data)

a  1   -0.902378
   2   -1.512923
   3   -1.082350
b  1   -0.900975
   2   -1.723988
   3   -0.791613
c  1   -1.631530
   2    2.290227
d  2    0.530892
   3    1.199453
dtype: float64

print("----------print data.index-------------")
print(data.index)

MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
           codes=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])


print("----------print data.index.levels[0]----------------")
print(data.index.levels[0])

Index(['a', 'b', 'c', 'd'], dtype='object')

print("----------print data.index.levels[1]----------------")
print(data.index.levels[1])

Int64Index([1, 2, 3], dtype='int64')

总结分析如下:
level中的唯一标签值集合分别为[‘a’, ‘b’, ‘c’, ‘d’]和[1, 2, 3]。
data.index.levels[0]上的标签abcd对应的索引为0123。data.index.levels[1]上的标签123对应的索引为012。
外层level的label值[0, 0, 0, 1, 1, 1, 2, 2, 3, 3]表示对应的标签值分别出现几次:a和b为3次,c和d为2次
内层level的label值[0, 1, 2, 0, 1, 2, 0, 1, 1, 2]按个数与外层label相对应。例如:外层a出现3次,则内层label的前3个值与a相对应,这三个索引值为0,1,2,分别对应1,2,3。

MultiIndex创建的方式

第一种

我们在创建Series或DataFrame时,可以通过给index(columns)参数传递多维数组,进而构建多维索引。【数组中每个维度对应位置的元素,组成每个索引值】
多维索引的也可以设置名称(names属性),属性的值为一维数组,元素的个数需要与索引的层数相同(每层索引都需要具有一个名称)。

import pandas as pd
import numpy as np

# 创建多层索引的第一种方式
# 创建Series对象,具有单层索引。
s1 = pd.Series([1, 2, 3], index=["a", "b", "c"])
print(s1)

a    1
b    2
c    3
dtype: int64


# 创建多层索引。多层索引需要一个二维的数组,每个元素(一维数组)来指定每个层级的索引。顺序
# 由高层(左边)到底层(右边)。

s2 = pd.Series([1, 2, 3, 4], index=[["a", "a", "b", "b"], ["c", "d", "e", "f"], ["m", "m", "k", "t"]])
print(s2)

a  c  m    1
   d  m    2
b  e  k    3
   f  t    4
dtype: int64

print("-------df--------")
df = pd.DataFrame(np.random.random(size=(4, 4)), index=[["上半年", "上半年", "下半年", "下半年"],
                                                        ["第一季度", "第二季度", "第三季度", "第四季度"]],
                  columns=[["水果", "水果", "蔬菜", "蔬菜"], ["苹果", "葡萄", "白菜", "萝卜"]])
print(df)

                水果                  蔬菜          
                苹果        葡萄        白菜        萝卜
上半年       第一季度  0.356637  0.358602  0.402864  0.550727
            第二季度  0.963110  0.010293  0.378511  0.051015
下半年       第三季度  0.098882  0.394281  0.554502  0.676566
             第四季度  0.828770  0.506423  0.681128  0.542206

print(df.index)

MultiIndex(levels=[['上半年', '下半年'], ['第一季度', '第三季度', '第二季度', '第四季度']],
           codes=[[0, 0, 1, 1], [0, 2, 1, 3]])

print(df.columns)

MultiIndex(levels=[['水果', '蔬菜'], ['白菜', '苹果', '萝卜', '葡萄']],
           codes=[[0, 0, 1, 1], [1, 3, 0, 2]])

如果是单层索引,我们可以通过索引对象的name属性来设置索引的名称。

s2 = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
s2.index.name = "索引名称"
print("--------s2----------")
print(s2)

索引名称
a    1
b    2
c    3
d    4
dtype: int64

对于多层索引,也可以设置索引的名称,此时,设置名称的属性为names(通过一维数组来设置)。
每层索引都具有名称。
修改df的索引

df.index.names = ["年度", "季度"]
df.columns.names = ["大类别", "小类别"]
print(df)

大类别             水果                  蔬菜          
小类别             苹果        葡萄        白菜        萝卜
年度  季度                                          
上半年 第一季度  0.078253  0.961293  0.770540  0.267522
      第二季度  0.845138  0.239290  0.208779  0.347256
下半年 第三季度  0.869534  0.148100  0.046563  0.753004
      第四季度  0.926966  0.305344  0.379041  0.467218

第二种

我们可以通过MultiIndex类的相关方法,预先创建一个MultiIndex对象,然后作为Series与DataFrame中的index(或columns)参数值。同时,可以通过names参数指定多层索引的名称。
from_arrays:接收一个多维数组参数,高维指定高层索引,低维指定底层索引。
from_tuples:接收一个元组的列表,每个元组指定每个索引(高维索引,低维索引)。
from_product:接收一个可迭代对象的列表,根据多个可迭代对象元素的笛卡尔积进行创建索引。
from_product相对于前两个方法而言,实现相对简单,但是,也存在局限。

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.random(size=(4, 4)), index=[["上半年", "上半年", "下半年", "下半年"],
                                                        ["第一季度", "第二季度", "第三季度", "第四季度"]],
                  columns=[["水果", "水果", "蔬菜", "蔬菜"], ["苹果", "葡萄", "白菜", "萝卜"]])
print(df)

                水果                  蔬菜          
                苹果        葡萄        白菜        萝卜
上半年 第一季度  0.645330  0.408014  0.121088  0.106337
       第二季度  0.671892  0.212711  0.792635  0.031329
下半年 第三季度  0.063841  0.513930  0.342464  0.885220
      第四季度  0.091936  0.745129  0.905859  0.760001

创建多层索引的第二种方式
------------from_arrays-------------------
from_arrays 参数为一个二维数组,每个元素(一维数组)来分别制定每层索引的内容。

mindex_arrsys = pd.MultiIndex.from_arrays([["上半年", "上半年", "下半年", "下半年"], ["1季度", "2季度", "3季度", "4季度"]])
df2 = pd.DataFrame(np.random.random(size=(4, 4)), index=mindex_arrsys)
print(df2)

                0         1         2         3
上半年 1季度  0.578044  0.636138  0.497155  0.389131
       2季度  0.195453  0.623200  0.769118  0.637451
下半年 3季度  0.562462  0.629691  0.684193  0.981682
      4季度  0.873525  0.489149  0.883518  0.252548

------------from_tuples-------------------
from_tuples 参数为一个(嵌套的)可迭代对象,元素为元祖类型。元祖的格式为:(高层索引内容,低层索引内容)
mindex_tuples = pd.MultiIndex.from_tuples([("上半年", "1季度"), ("上半年", "2季度"), ("下半年", "3季度"), ("下半年", "4季度")])
df3 = pd.DataFrame(np.random.random(size=(4, 4)), index=mindex_tuples)
print(df3)

                0         1         2         3
上半年 1季度  0.843825  0.242793  0.132814  0.024581
    2季度  0.404961  0.870869  0.134744  0.220976
下半年 3季度  0.196361  0.074073  0.588173  0.181438
    4季度  0.936489  0.246351  0.941209  0.144210

------------from_products-------------------
使用笛卡尔积的方式来创建多层索引。参数为嵌套的可迭代对象。结果为使用每个一维数组中的元素与其他一维数组中的元素来生成
索引内容。

mindex_products = pd.MultiIndex.from_product([["a", "b"], ["c", "d"]], names=["outer", "inner"])
print(mindex_products)

MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=['outer', 'inner'])

print(pd.MultiIndex.from_arrays([["a", "a", "b", "b"], ["c", "d", "c", "d"]]))

MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]])

print(pd.MultiIndex.from_arrays([["a", "a", "b"], ["c", "d", "d"]]))

MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1], [0, 1, 1]])

小结
MultiIndex的三个类方法,可以创建MultiIndex类型的对象。三种方式相比,第三种方式(笛卡尔积的方式)更加简便,但是,
其也具有一定的局限:两两组合必须都存在,否则,就不能使用这种方式。
在创建多层索引对象时,可以通过names参数来指定每个索引层级的名称。

df4 = pd.DataFrame(np.random.random(size=(4, 4)),index=mindex_products)
print(df4)
print(df4.index)

                    0         1         2         3
outer inner                                        
a     c      0.213218  0.561547  0.224423  0.764169
      d      0.296970  0.557486  0.809295  0.300886
b     c      0.134809  0.111138  0.619714  0.223240
      d      0.707181  0.872395  0.800698  0.676075
MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=['outer', 'inner'])

第三种方式

(因为繁琐,所以不用),最直接的方式:

mindex = pd.MultiIndex(levels=[['a', 'b'], ['c', 'd']],
                       codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
                       names=['outer', 'inner'])
print(mindex)

MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=['outer', 'inner'])

多层索引操作

对于多层索引,同样也支持单层索引的相关操作,例如,索引元素,切片,索引数组选择元素等。我们也可以根据多级索引,按层次逐级选择元素。
多层索引的优势:通过创建多层索引,我们就可以使用高层次的索引,来操作整个索引组的数据。
格式:
s[操作]
s.loc[操作]
s.iloc[操作]
其中,操作可以是索引,切片,数组索引,布尔索引。
Series多层索引
通过loc(标签索引)操作,可以通过多层索引,获取该索引所对应的一组值。
通过iloc(位置索引)操作,会获取对应位置的元素值(与是否多层索引无关)。
通过s[操作]的行为有些诡异,建议不用。
对于索引(单级),首先按照标签选择,如果标签不存在,则按照位置选择。
对于多级索引,则按照标签进行选择。
对于切片,如果提供的是整数,则按照位置选择,否则按照标签选择。
对于数组索引, 如果数组元素都是整数,则根据位置进行索引,否则,根据标签进行索引(此时如果标签不存在,也不会出现错误)。

import pandas as pd

s = pd.Series([1, 2, 3, 4], index=[["a", "a", "b", "b"], ["c", "d", "e", "f"]])
print(s)

a  c    1
   d    2
b  e    3
   f    4
dtype: int64

# 多层索引的优势,可以一次获取一组元素(值)
print(s.loc["a"])

c    1
d    2
dtype: int64

# 也可以沿着索引层次进行访问。
print(s.loc["a", "d"]) # 访问指定坐标的元素值

2

# 通过位置索引访问元素,与多层索引没有任何关系。
print(s.iloc[0])

1


# 切片
print(s.loc["a":"b"])

a  c    1
   d    2
b  e    3
   f    4
dtype: int64

# 行index上的序号类型的切片
print(s.iloc[0:2])

a  c    1
   d    2
b  e    3
   f    4
dtype: int64

DataFrame多层索引

通过loc(标签索引)操作,可以通过多层索引,获取该索引所对应的一组值。
通过iloc(位置索引)操作,会获取对应位置的一行(与是否多层索引无关)。
通过s[操作]的行为有些诡异,建议不用。
对于索引,根据标签获取相应的列(如果是多层索引,则可以获得多列)。
对于数组索引, 根据标签,获取相应的列(如果是多层索引,则可以获得多列)。
对于切片,首先按照标签进行索引,然后再按照位置进行索引(取行)。

import pandas as pd
data=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
df=pd.DataFrame(data)
print(df)

    0   1   2   3
0   1   2   3   4
1   5   6   7   8
2   9  10  11  12
3  13  14  15  16

# 指定行索引
df.index=[["a", "a", "b", "b"], ["c", "d", "c", "d"]]
# 指定列索引
df.columns=[["x", "x", "y", "y"], ["z", "u", "z", "u"]]
print("-----------指定行和列索引之后的数据值---------------")
print(df)

      x       y    
      z   u   z   u
a c   1   2   3   4
  d   5   6   7   8
b c   9  10  11  12
  d  13  14  15  16

print('-------df.loc["a"]------------')
print(df.loc["a"]) # 对应的外层索引的切片

   x     y   
   z  u  z  u
c  1  2  3  4
d  5  6  7  8

print('--------df.loc["a", "c"]-----------')
print(df.loc["a", "c"])   #取的是对应的行数据

x  z    1
   u    2
y  z    3
   u    4

print('------df["x", "z"])--------')
print(df["x", "z"]) #取的是列数据

a  c     1
   d     5
b  c     9
   d    13
Name: (x, z), dtype: int64

通过位置访问元素与是否多层索引无关。

print('----------df.iloc[0])-----------------')
print(df.iloc[0])

x  z    1
   u    2
y  z    3
   u    4
Name: (a, c), dtype: int64

交换索引

我们可以调用DataFrame对象的swaplevel方法来交换两个层级索引。该方法默认对倒数第2层与倒数第1层进行交换。我们也可以指定交换的层。层次从0开始,由外向内递增(或者由上到下递增),也可以指定负值,负值表示倒数第n层。除此之外,我们也可以使用层次索引的名称来进行交换。

# 交换索引的层级,可以以一种不同的方式来进行展示(统计)。
import pandas as pd
data=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
df = pd.DataFrame(data, index=[["a", "a", "b", "b"],
            ["north", "north", "south", "south"], [2017, 2018, 2017, 2018]])
print(df)

               0   1   2   3
a north 2017   1   2   3   4
        2018   5   6   7   8
b south 2017   9  10  11  12
        2018  13  14  15  16

# 层级:从外层到内层,值为0, 1, 2……,同时,层级也可以为负值,表示倒数第n个层级(由内层到外层)。
# 例如,-1表示最内层。
# 如果没有显式指定交换的层级,则默认交换最内层的两个层级。
df = df.swaplevel(0, 2)
print(df)

               0   1   2   3
2017 north a   1   2   3   4
2018 north a   5   6   7   8
2017 south b   9  10  11  12
2018 south b  13  14  15  16

索引名字的作用。

除了数值来指定索引的层级外,我们也可以通过索引的名字来指定索引的层级。

df.index.names = ["x", "area", "year"]
df.swaplevel("area", "year")
print(df)

                  0   1   2   3
x    area  year                
2017 north a      1   2   3   4
2018 north a      5   6   7   8
2017 south b      9  10  11  12
2018 south b     13  14  15  16

df.sort_index()
print(df)

                 0   1   2   3
x    area  year                
2017 north a      1   2   3   4
2018 north a      5   6   7   8
2017 south b      9  10  11  12
2018 south b     13  14  15  16

索引排序

我们可以使用sort_index方法对索引进行排序处理。

level:指定根据哪一层进行排序,默认为最外(上)层。该值可以是数值,索引名,或者是由二者构成的列表。
inplace:是否就地修改。默认为False。

# 层级索引的排序
df = pd.DataFrame(data, index=[["b", "a", "c", "c"],
            ["c", "y", "k", "k"], [3, -2, 5, 2]])
print(df)

         0   1   2   3
b c  3   1   2   3   4
a y -2   5   6   7   8
c k  5   9  10  11  12
     2  13  14  15  16

# 在对索引进行排序时,可以通过level参数指定索引的层级(排序的层级)。
# 如果没有显式指定,则默认为最外层的层级(层级为0)。
# 当我们对某个层级进行排序时,该层级的所有内层层级也会进行排序。
print(df.sort_index())

         0   1   2   3
a y -2   5   6   7   8
b c  3   1   2   3   4
c k  2  13  14  15  16
     5   9  10  11  12

print(df.sort_index(level=1))

         0   1   2   3
b c  3   1   2   3   4
c k  2  13  14  15  16
     5   9  10  11  12
a y -2   5   6   7   8

索引堆叠

通过DataFrame对象的stack方法,可以进行索引堆叠,即将指定层级的列转换成行。
level:指定转换的层级,默认为-1。
*详见 Python--pandas--unstack() 与stack()
取消堆叠
通过DataFrame对象的unstack方法,可以取消索引堆叠,即将指定层级的行转换成列。
level:指定转换的层级,默认为-1。
fill_value:指定填充值。默认为NaN。
详见: Python--pandas--unstack() 与stack()

设置索引

在DataFrame中,如果我们需要将现有的某一(几)列作为索引列,可以调用set_index方法来实现。
drop:是否丢弃作为新索引的列,默认为True。
append:是否以追加的方式设置索引,默认为False。
inplace:是否就地修改,默认为False。
详见Python-pandas--set_index与reset_index

重置索引

调用在DataFrame对象的reset_index,可以重置索引。该操作与set_index正好相反。
level:重置索引的层级,默认重置所有层级的索引。如果重置所有索引,将会创建默认整数序列索引。
drop:是否丢弃重置的索引列,默认为False。
inplace:是否就地修改,默认为False。
详见 Python-pandas--set_index与reset_index

bond_sql_short
Out[80]: 
               deal_no   deal_time bond_code our_side  amount_par
0    CBT20180409003026  2018-04-09    180002       买入     4000.00
1    CBT20180410002391  2018-04-10    170016       买入     6000.00
2    CBT20180416000050  2018-04-16    180007       买入    10000.00
3    CBT20180423002224  2018-04-23    160012       买入    10000.00
4    CBT20180507001371  2018-05-07    180007       买入     5000.00
..                 ...         ...       ...      ...         ...
167  CBT20210125203615  2021-01-25    190409       买入     2000.00
168  CBT20210129300873  2021-01-29    190203       卖出    -5000.00
169  CBT20210129301353  2021-01-29    190203       卖出    -5000.00
170  CBT20210129302989  2021-01-29    190203       卖出    -3000.00
171  CBT20210129303230  2021-01-29    190203       卖出    -5000.00

bond_sql_short.set_index(['bond_code','deal_time'],inplace = True)
#得到:
                                deal_no our_side  amount_par
bond_code deal_time                                         
180002    2018-04-09  CBT20180409003026       买入     4000.00
170016    2018-04-10  CBT20180410002391       买入     6000.00
180007    2018-04-16  CBT20180416000050       买入    10000.00
160012    2018-04-23  CBT20180423002224       买入    10000.00
180007    2018-05-07  CBT20180507001371       买入     5000.00
                                ...      ...         ...
190409    2021-01-25  CBT20210125203615       买入     2000.00
190203    2021-01-29  CBT20210129300873       卖出    -5000.00
          2021-01-29  CBT20210129301353       卖出    -5000.00
          2021-01-29  CBT20210129302989       卖出    -3000.00
          2021-01-29  CBT20210129303230       卖出    -5000.00

bond_sql_short.index
Out[0]: 
MultiIndex([('180002', '2018-04-09'),
            ('170016', '2018-04-10'),
            ('180007', '2018-04-16'),
            ('160012', '2018-04-23'),
            ('180007', '2018-05-07'),
            ('160007', '2018-05-14'),
            ('170016', '2018-05-18'),
            ('180007', '2018-05-21'),
            ('150014', '2018-07-03'),
            ('180013', '2018-07-09'),
            ...
            ('209950', '2021-01-13'),
            ('209950', '2021-01-13'),
            ('209950', '2021-01-13'),
            ('200203', '2021-01-20'),
            ('200402', '2021-01-20'),
            ('190409', '2021-01-25'),
            ('190203', '2021-01-29'),
            ('190203', '2021-01-29'),
            ('190203', '2021-01-29'),
            ('190203', '2021-01-29')],
           names=['bond_code', 'deal_time'], length=172)

#索引的引用:(一次调用,多个结果)
bond_sql_short.loc['190203']
Out[87]: 
                      deal_no our_side  amount_par
deal_time                                         
2019-09-12  CBT20190912302174       买入    20000.00
2019-09-16  CBT20190916303106       买入     5000.00
2019-09-16  CBT20190916303704       买入     5000.00
2019-10-10  CBT20191010302001       买入    10000.00
2020-03-11  CBT20200311300446       卖出   -10000.00
2021-01-29  CBT20210129300873       卖出    -5000.00
2021-01-29  CBT20210129301353       卖出    -5000.00
2021-01-29  CBT20210129302989       卖出    -3000.00
2021-01-29  CBT20210129303230       卖出    -5000.00

多重索引的引用 (切片筛选index)

可以使用loc定位 df.loc[('A',slice(None)),:]
各参数的解释如下:
loc[(a,b),c]中第一个参数元组为索引内容,a为level0索引对应的内容,b为level1索引对应的内容
因为df是一个dataframe,所以要用c来指定列,这里‘A’,指选择class中的A类
slice(None), 是Python中的切片操作,这里用来选择任意的id,要注意!不能使用‘:’来指定任意index
‘:’,用来指定dataframe任意的列

(以下原创)
#样表df:gp_avg
                      票面合计        利息合计   利率     天数  利率(加权)  天数(加权)
YM      分行名称                                                      
2020-05 上海分行  100000000.00  1937797.30 2.02 345.35    2.02  345.35
2020-12 广州分行  299259316.30  3208921.68 2.80 133.80    2.88  132.82
2021-01 上海分行   84981492.32  1883749.78 3.60 187.29    3.60  221.52
        广州分行   80000000.00   717597.60 3.05 105.88    3.05  105.88
        深圳分行  100000000.00  1181180.00 3.65 116.50    3.65  116.50
2021-02 上海分行  835865918.66  8046120.93 3.61  92.37    3.63   96.56
        广州分行  133562381.72  1306665.17 3.45  61.25    3.70   93.53
        汕头分行  307498735.72  2057071.26 3.83  76.29    3.91   61.95
        深圳分行  292845822.74  2437096.53 3.81  92.49    3.95   76.58
2021-03 上海分行 1934993445.32 10566908.95 3.01  57.09    3.09   61.85
        广州分行 2170776185.37 17508861.21 3.29  72.20    3.30   88.65
        汕头分行  627034608.86  4910113.03 3.42  67.45    3.29   85.04
        深圳分行  310963602.01  1790793.95 3.26  61.58    3.22   64.39

其中:
gp_avg.columns
Out[1]: Index(['票面合计', '利息合计', '利率', '天数', '利率(加权)', '天数(加权)'], dtype='object')

gp_avg.index
Out[2]: 
MultiIndex([('2020-05', '上海分行'),
            ('2020-12', '广州分行'),
            ('2021-01', '上海分行'),
            ('2021-01', '广州分行'),
            ('2021-01', '深圳分行'),
            ('2021-02', '上海分行'),
            ('2021-02', '广州分行'),
            ('2021-02', '汕头分行'),
            ('2021-02', '深圳分行'),
            ('2021-03', '上海分行'),
            ('2021-03', '广州分行'),
            ('2021-03', '汕头分行'),
            ('2021-03', '深圳分行')],
           names=['YM', '分行名称'])

#下面开始切啦,先横着切一天的
gp_avg.loc[('2021-03',slice(None))]
Out[3]: 
              票面合计        利息合计   利率    天数  利率(加权)  天数(加权)
分行名称                                                     
上海分行 1934993445.32 10566908.95 3.01 57.09    3.09   61.85
广州分行 2170776185.37 17508861.21 3.29 72.20    3.30   88.65
汕头分行  627034608.86  4910113.03 3.42 67.45    3.29   85.04
深圳分行  310963602.01  1790793.95 3.26 61.58    3.22   64.39

#切两天的:
gp_avg.loc[['2020-12','2021-02']]
Out[4]: 
                     票面合计       利息合计   利率     天数  利率(加权)  天数(加权)
YM      分行名称                                                    
2020-12 广州分行 299259316.30 3208921.68 2.80 133.80    2.88  132.82
2021-02 上海分行 835865918.66 8046120.93 3.61  92.37    3.63   96.56
        广州分行 133562381.72 1306665.17 3.45  61.25    3.70   93.53
        汕头分行 307498735.72 2057071.26 3.83  76.29    3.91   61.95
        深圳分行 292845822.74 2437096.53 3.81  92.49    3.95   76.58

#再竖着切广州分行的:
gp_avg.loc[(slice(None),'广州分行'),]  #和gp_avg.loc[(slice(None),'广州分行'),:]效果一样
Out[5]: 
                      票面合计        利息合计   利率     天数  利率(加权)  天数(加权)
YM      分行名称                                                      
2020-12 广州分行  299259316.30  3208921.68 2.80 133.80    2.88  132.82
2021-01 广州分行   80000000.00   717597.60 3.05 105.88    3.05  105.88
2021-02 广州分行  133562381.72  1306665.17 3.45  61.25    3.70   93.53
2021-03 广州分行 2170776185.37 17508861.21 3.29  72.20    3.30   88.65

#切一列的
gp_avg.loc[(slice(None),'广州分行'),'利息合计']
Out[6]: 
YM       分行名称
2020-12  广州分行    3208921.68
2021-01  广州分行     717597.60
2021-02  广州分行    1306665.17
2021-03  广州分行   17508861.21
Name: 利息合计, dtype: float64

#索引交换层级
gp_avg.swaplevel()
Out[7]: 
                      票面合计        利息合计   利率     天数  利率(加权)  天数(加权)
分行名称 YM                                                           
上海分行 2020-05  100000000.00  1937797.30 2.02 345.35    2.02  345.35
广州分行 2020-12  299259316.30  3208921.68 2.80 133.80    2.88  132.82
上海分行 2021-01   84981492.32  1883749.78 3.60 187.29    3.60  221.52
广州分行 2021-01   80000000.00   717597.60 3.05 105.88    3.05  105.88
深圳分行 2021-01  100000000.00  1181180.00 3.65 116.50    3.65  116.50
上海分行 2021-02  835865918.66  8046120.93 3.61  92.37    3.63   96.56
广州分行 2021-02  133562381.72  1306665.17 3.45  61.25    3.70   93.53
汕头分行 2021-02  307498735.72  2057071.26 3.83  76.29    3.91   61.95
深圳分行 2021-02  292845822.74  2437096.53 3.81  92.49    3.95   76.58
上海分行 2021-03 1934993445.32 10566908.95 3.01  57.09    3.09   61.85
广州分行 2021-03 2170776185.37 17508861.21 3.29  72.20    3.30   88.65
汕头分行 2021-03  627034608.86  4910113.03 3.42  67.45    3.29   85.04
深圳分行 2021-03  310963602.01  1790793.95 3.26  61.58    3.22   64.39

参考博客

https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html
https://www.jianshu.com/p/2c1c8fbee55a
https://zhuanlan.zhihu.com/p/569288664
http://www.python66.com/pandasshujufenxi/472.html

posted on 2020-10-14 20:27  chengjon  阅读(682)  评论(0编辑  收藏  举报