# http://pandas.pydata.org/pandas-docs/stable/advanced.html
# MultiIndex / Advanced Indexing
# pandas 0.22.0
# http://pandas.pydata.org/pandas-docs/stable/advanced.html
# MultiIndex / Advanced Indexing
# pandas 0.22.0
import pandas as pd
import numpy as np
import random; random.shuffle(tuples)
import pandas as pd
import numpy as np
import random; random.shuffle(tuples)
# Hierarchical indexing (MultiIndex) 分层索引 多重索引
# 创建多重索引对象,如同标准的索引类,他们存放轴axis标签labels
# 创建方式:
# from a list of arrays -- using MultiIndex.from_arrays
# from an array of tuples -- using MultiIndex.from_tuples
# from a crossed set of iterables -- using MultiIndex.from_product
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
arrays
# *arrays
zip(*arrays) # 这里的* 是“解开”list , list[0] list[1] ……
list(zip(*arrays))
list(zip(arrays[0], arrays[1]))
tuples = list(zip(*arrays))
tuples
# Hierarchical indexing (MultiIndex) 分层索引 多重索引
# 创建多重索引对象,如同标准的索引类,他们存放轴axis标签labels
# 创建方式:
# from a list of arrays -- using MultiIndex.from_arrays
# from an array of tuples -- using MultiIndex.from_tuples
# from a crossed set of iterables -- using MultiIndex.from_product
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
arrays
# *arrays
zip(*arrays) # 这里的* 是“解开”list , list[0] list[1] ……
list(zip(*arrays))
list(zip(arrays[0], arrays[1]))
tuples = list(zip(*arrays))
tuples
[['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
<zip at 0xf96f888>
[('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')]
[('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')]
[('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')]
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
index
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
index
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
names=['first', 'second'])
s = pd.Series(np.random.randn(8), index=index)
s
s = pd.Series(np.random.randn(8), index=index)
s
first second
bar one 0.271000
two -1.276230
baz one -1.018103
two -0.620292
foo one 1.008070
two 0.759145
qux one -2.141050
two -0.927688
dtype: float64
# 更简洁的方式, 当每个元素对都来自于可迭代对象时
iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']] # 创建了与上面相同的index
pd.MultiIndex.from_product(iterables, names=['first', 'second']) # 多重索引可以接受命名,默认为None
# 更简洁的方式, 当每个元素对都来自于可迭代对象时
iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']] # 创建了与上面相同的index
pd.MultiIndex.from_product(iterables, names=['first', 'second']) # 多重索引可以接受命名,默认为None
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
names=['first', 'second'])
# 也可以直接在创建df或series时传入矩阵array 的 列表list
arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]
arrays
# 也可以直接在创建df或series时传入矩阵array 的 列表list
arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]
arrays
[array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
dtype='<U3'),
array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'],
dtype='<U3')]
s = pd.Series(np.random.randn(8), index=arrays)
s
s = pd.Series(np.random.randn(8), index=arrays)
s
bar one 0.817791
two 0.510420
baz one -0.494160
two -0.529997
foo one 0.641282
two -0.202762
qux one 0.050320
two 2.097300
dtype: float64
df = pd.DataFrame(np.random.randn(8, 4), index=arrays)
df
df = pd.DataFrame(np.random.randn(8, 4), index=arrays)
df
0 | 1 | 2 | 3 | ||
bar | one | -2.090989 | 0.001052 | 1.467637 | 0.267938 |
two | 1.224610 | 0.851894 | 0.765531 | -0.505116 | |
baz | one | 1.444246 | -0.247795 | 0.267462 | -0.945641 |
two | 0.836046 | 0.274732 | 0.530525 | -0.560081 | |
foo | one | -3.709465 | -0.157089 | 0.608778 | -0.003217 |
two | -0.848818 | 1.478306 | -0.389401 | -1.205956 | |
qux | one | -1.069775 | 1.272440 | -0.797613 | -0.194223 |
two | 1.597218 | 0.454815 | -0.756022 | 0.481038 |
# 可以对不同的轴向(如行索引/行名或列索引/列名)设置
df = pd.DataFrame(np.random.randn(3, 8), index=['A', 'B', 'C'], columns=index)
df
# 可以对不同的轴向(如行索引/行名或列索引/列名)设置
df = pd.DataFrame(np.random.randn(3, 8), index=['A', 'B', 'C'], columns=index)
df
first | bar | baz | foo | qux | ||||
second | one | two | one | two | one | two | one | two |
A | -1.608162 | -0.007312 | 1.048244 | -0.029907 | -0.437866 | -1.853398 | 2.026875 | 0.359521 |
B | 1.207609 | -0.272366 | -0.530191 | -0.689641 | -0.244362 | -1.476252 | 0.818493 | 0.353771 |
C | -0.369463 | 1.862253 | -0.118297 | -0.148326 | 1.147616 | -1.389965 | 0.817716 | 0.787394 |
# 同时对两个方向设置index,注意index的长度与数据在不同方向上的长度
pd.DataFrame(np.random.randn(6, 6), index=index[:6], columns=index[:6])
# 同时对两个方向设置index,注意index的长度与数据在不同方向上的长度
pd.DataFrame(np.random.randn(6, 6), index=index[:6], columns=index[:6])
first | bar | baz | foo | ||||
second | one | two | one | two | one | two | |
first | second | ||||||
bar | one | 0.020204 | -0.549089 | 0.381830 | 0.326558 | -1.420590 | -1.551863 |
two | 1.311775 | 2.294908 | 0.203981 | 1.381199 | -0.743387 | 2.119027 | |
baz | one | 0.640856 | 1.089627 | -1.463503 | 0.727607 | -0.959549 | -0.037316 |
two | -0.906859 | -0.720702 | 0.862614 | 0.082066 | 0.209276 | -0.391039 | |
foo | one | -0.328704 | -1.015117 | 0.279826 | 0.141166 | -0.053601 | -1.171920 |
two | 0.342074 | -0.196049 | -0.387946 | 0.196228 | -1.264932 | 0.144251 |
pd.Series(np.random.randn(8), index=tuples) # 多重索引,相当于元组index
pd.Series(np.random.randn(8), index=tuples) # 多重索引,相当于元组index
(bar, one) -0.267177
(bar, two) -0.239632
(baz, one) 1.212249
(baz, two) 0.289517
(foo, one) 1.311922
(foo, two) -0.797733
(qux, one) -1.395485
(qux, two) -0.451327
dtype: float64
# 可以控制索引的显示方式,通过在 pandas.set_options() 设置 multi_sparse 选项
pd.set_option('display.multi_sparse', False)
df
pd.set_option('display.multi_sparse', True)
df
# 可以控制索引的显示方式,通过在 pandas.set_options() 设置 multi_sparse 选项
pd.set_option('display.multi_sparse', False)
df
pd.set_option('display.multi_sparse', True)
df
first | bar | bar | baz | baz | foo | foo | qux | qux |
second | one | two | one | two | one | two | one | two |
A | -1.608162 | -0.007312 | 1.048244 | -0.029907 | -0.437866 | -1.853398 | 2.026875 | 0.359521 |
B | 1.207609 | -0.272366 | -0.530191 | -0.689641 | -0.244362 | -1.476252 | 0.818493 | 0.353771 |
C | -0.369463 | 1.862253 | -0.118297 | -0.148326 | 1.147616 | -1.389965 | 0.817716 | 0.787394 |
first | bar | baz | foo | qux | ||||
second | one | two | one | two | one | two | one | two |
A | -1.608162 | -0.007312 | 1.048244 | -0.029907 | -0.437866 | -1.853398 | 2.026875 | 0.359521 |
B | 1.207609 | -0.272366 | -0.530191 | -0.689641 | -0.244362 | -1.476252 | 0.818493 | 0.353771 |
C | -0.369463 | 1.862253 | -0.118297 | -0.148326 | 1.147616 | -1.389965 | 0.817716 | 0.787394 |
# Reconstructing the level labels 重建层级标签
# The method get_level_values will return a vector of the labels for each location at a particular level:
# get_level_values 方法返回指定层级的标签向量
index.get_level_values(0) # 使用整数序号
index.get_level_values("second") # 使用name
# Reconstructing the level labels 重建层级标签
# The method get_level_values will return a vector of the labels for each location at a particular level:
# get_level_values 方法返回指定层级的标签向量
index.get_level_values(0) # 使用整数序号
index.get_level_values("second") # 使用name
Index(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], dtype='object', name='first')
Index(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'], dtype='object', name='second')
# Basic indexing on axis with MultiIndex # 在轴方向的基础索引
df['bar']
df['bar', 'one']
df['bar']['one'] # 不建议使用,链式
s['qux']
# Basic indexing on axis with MultiIndex # 在轴方向的基础索引
df['bar']
df['bar', 'one']
df['bar']['one'] # 不建议使用,链式
s['qux']
second | one | two |
A | -1.608162 | -0.007312 |
B | 1.207609 | -0.272366 |
C | -0.369463 | 1.862253 |
A -1.608162
B 1.207609
C -0.369463
Name: (bar, one), dtype: float64
A -1.608162
B 1.207609
C -0.369463
Name: one, dtype: float64
one 0.05032
two 2.09730
dtype: float64
# Defined Levels 指定层级
df.columns # 原index
df[['foo','qux']].columns # 切片后的结果,层级levels中的项目没有减少,labels减少了
# 这样做避免了重新计算层级,使切片保持高效
# Defined Levels 指定层级
df.columns # 原index
df[['foo','qux']].columns # 切片后的结果,层级levels中的项目没有减少,labels减少了
# 这样做避免了重新计算层级,使切片保持高效
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
names=['first', 'second'])
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
labels=[[2, 2, 3, 3], [0, 1, 0, 1]],
names=['first', 'second'])
# 查看切片实际选择levels
df[['foo','qux']].columns.values
df[['foo','qux']].columns.get_level_values(0) # 指定层级
# 查看切片实际选择levels
df[['foo','qux']].columns.values
df[['foo','qux']].columns.get_level_values(0) # 指定层级
array([('foo', 'one'), ('foo', 'two'), ('qux', 'one'), ('qux', 'two')],
dtype=object)
Index(['foo', 'foo', 'qux', 'qux'], dtype='object', name='first')
# 用有效的used层级重建多重索引
df[['foo','qux']].columns.remove_unused_levels()
# 用有效的used层级重建多重索引
df[['foo','qux']].columns.remove_unused_levels()
MultiIndex(levels=[['foo', 'qux'], ['one', 'two']],
labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
names=['first', 'second'])
# Data alignment and using reindex 数据定位和使用reindex
s
# Data alignment and using reindex 数据定位和使用reindex
s
bar one 0.817791
two 0.510420
baz one -0.494160
two -0.529997
foo one 0.641282
two -0.202762
qux one 0.050320
two 2.097300
dtype: float64
# 当两个index不同的对象计算时与一般的index一样
s + s[:-2]
s + s[::2]
# 当两个index不同的对象计算时与一般的index一样
s + s[:-2]
s + s[::2]
bar one 1.635582
two 1.020840
baz one -0.988319
two -1.059993
foo one 1.282563
two -0.405523
qux one NaN
two NaN
dtype: float64
bar one 1.635582
two NaN
baz one -0.988319
two NaN
foo one 1.282563
two NaN
qux one 0.100640
two NaN
dtype: float64
# reindex 可以被另外一个 multiindex 或者 元组的list 或 array 调用
index
index[:3]
s.reindex(index[:3])
s.reindex([('foo', 'two'), ('bar', 'one'), ('qux', 'one'), ('baz', 'one')])
# reindex 可以被另外一个 multiindex 或者 元组的list 或 array 调用
index
index[:3]
s.reindex(index[:3])
s.reindex([('foo', 'two'), ('bar', 'one'), ('qux', 'one'), ('baz', 'one')])
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
names=['first', 'second'])
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
labels=[[0, 0, 1], [0, 1, 0]],
names=['first', 'second'])
first second
bar one 0.817791
two 0.510420
baz one -0.494160
dtype: float64
foo two -0.202762
bar one 0.817791
qux one 0.050320
baz one -0.494160
dtype: float64
# Advanced indexing with hierarchical index
# 使用层次索引的高级索引方法
df = df.T
df
# Advanced indexing with hierarchical index
# 使用层次索引的高级索引方法
df = df.T
df
A | B | C | ||
first | second | |||
bar | one | -1.608162 | 1.207609 | -0.369463 |
two | -0.007312 | -0.272366 | 1.862253 | |
baz | one | 1.048244 | -0.530191 | -0.118297 |
two | -0.029907 | -0.689641 | -0.148326 | |
foo | one | -0.437866 | -0.244362 | 1.147616 |
two | -1.853398 | -1.476252 | -1.389965 | |
qux | one | 2.026875 | 0.818493 | 0.817716 |
two | 0.359521 | 0.353771 | 0.787394 |
# .loc 定位
df.loc["bar"]
df.loc["bar", "two"] # 返回了一个series(不是一行,而是“一列”),其索引是原df的列名
# .loc 定位
df.loc["bar"]
df.loc["bar", "two"] # 返回了一个series(不是一行,而是“一列”),其索引是原df的列名
A | B | C | |
second | |||
one | -1.608162 | 1.207609 | -0.369463 |
two | -0.007312 | -0.272366 | 1.862253 |
A -0.007312
B -0.272366
C 1.862253
Name: (bar, two), dtype: float64
# loc 中使用切片,切片的值可以是元组
df.loc['baz':'foo']
df.loc[('baz', 'two'):('qux', 'one')]
df.loc[('baz', 'two'):'foo']
# loc 中使用切片,切片的值可以是元组
df.loc['baz':'foo']
df.loc[('baz', 'two'):('qux', 'one')]
df.loc[('baz', 'two'):'foo']
A | B | C | ||
first | second | |||
baz | one | 1.048244 | -0.530191 | -0.118297 |
two | -0.029907 | -0.689641 | -0.148326 | |
foo | one | -0.437866 | -0.244362 | 1.147616 |
two | -1.853398 | -1.476252 | -1.389965 |
A | B | C | ||
first | second | |||
baz | two | -0.029907 | -0.689641 | -0.148326 |
foo | one | -0.437866 | -0.244362 | 1.147616 |
two | -1.853398 | -1.476252 | -1.389965 | |
qux | one | 2.026875 | 0.818493 | 0.817716 |
A | B | C | ||
first | second | |||
baz | two | -0.029907 | -0.689641 | -0.148326 |
foo | one | -0.437866 | -0.244362 | 1.147616 |
two | -1.853398 | -1.476252 | -1.389965 |
# 可以给loc传入元组或标签列表,取得不连续的索引
df.loc[[('bar', 'two'), ('qux', 'one')]]
# 可以给loc传入元组或标签列表,取得不连续的索引
df.loc[[('bar', 'two'), ('qux', 'one')]]
A | B | C | ||
first | second | |||
bar | two | -0.007312 | -0.272366 | 1.862253 |
qux | one | 2.026875 | 0.818493 | 0.817716 |
# Using slicers 使用切片
# 可以用多重索引对象进行切片。可以用 切片值、 标签或标签列表、 布尔索引等选择器
# 可以用slice(None) 选择那一级的所有的内容。不用特别指定所有深度的级别,他们默认是slice(None)
# 注意:使用loc应该规定所有的轴方向,包括行index和列columns。
# 推荐方式:df.loc[(slice('A1','A3'),.....), :] 注意 冒号前面的逗号,逗号前表示行方向切片(选择器),逗号后面表示列方向切片(选择器)
# 不推荐: df.loc[(slice('A1','A3'),.....)] 可能产生歧义
# Using slicers 使用切片
# 可以用多重索引对象进行切片。可以用 切片值、 标签或标签列表、 布尔索引等选择器
# 可以用slice(None) 选择那一级的所有的内容。不用特别指定所有深度的级别,他们默认是slice(None)
# 注意:使用loc应该规定所有的轴方向,包括行index和列columns。
# 推荐方式:df.loc[(slice('A1','A3'),.....), :] 注意 冒号前面的逗号,逗号前表示行方向切片(选择器),逗号后面表示列方向切片(选择器)
# 不推荐: df.loc[(slice('A1','A3'),.....)] 可能产生歧义
def mklbl(prefix, n):
# mklbl("a", 3) --> ['a0', 'a1', 'a2']
return ["%s%s" % (prefix, i) for i in range(n)]
def mklbl(prefix, n):
# mklbl("a", 3) --> ['a0', 'a1', 'a2']
return ["%s%s" % (prefix, i) for i in range(n)]
mklbl("a", 3)
mklbl("a", 3)
['a0', 'a1', 'a2']
miindex = pd.MultiIndex.from_product([mklbl('A',4),
mklbl('B',2),
mklbl('C',4),
mklbl('D',2)])
miindex # 由列表生成4重(4级)索引对象,共生成4*2*4*2=64行
miindex = pd.MultiIndex.from_product([mklbl('A',4),
mklbl('B',2),
mklbl('C',4),
mklbl('D',2)])
miindex # 由列表生成4重(4级)索引对象,共生成4*2*4*2=64行
MultiIndex(levels=[['A0', 'A1', 'A2', 'A3'], ['B0', 'B1'], ['C0', 'C1', 'C2', 'C3'], ['D0', 'D1']],
labels=[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]])
micolumns = pd.MultiIndex.from_tuples([('a','foo'),('a','bar'),
('b','foo'),('b','bah')],
names=['lvl0', 'lvl1'])
micolumns # 由元组生成2重索引对象,共4行,并对2重(两级)分别命名
micolumns = pd.MultiIndex.from_tuples([('a','foo'),('a','bar'),
('b','foo'),('b','bah')],
names=['lvl0', 'lvl1'])
micolumns # 由元组生成2重索引对象,共4行,并对2重(两级)分别命名
MultiIndex(levels=[['a', 'b'], ['bah', 'bar', 'foo']],
labels=[[0, 0, 1, 1], [2, 1, 2, 0]],
names=['lvl0', 'lvl1'])
row_l = len(miindex)
col_l = len(micolumns)
dfmi = pd.DataFrame(np.arange(row_l * col_l).reshape((row_l, col_l)),
index=miindex,
columns=micolumns).sort_index().sort_index(axis=1)
dfmi
row_l = len(miindex)
col_l = len(micolumns)
dfmi = pd.DataFrame(np.arange(row_l * col_l).reshape((row_l, col_l)),
index=miindex,
columns=micolumns).sort_index().sort_index(axis=1)
dfmi
lvl0 | a | b | |||||
lvl1 | bar | foo | bah | foo | |||
A0 | B0 | C0 | D0 | 1 | 0 | 3 | 2 |
D1 | 5 | 4 | 7 | 6 | |||
C1 | D0 | 9 | 8 | 11 | 10 | ||
D1 | 13 | 12 | 15 | 14 | |||
C2 | D0 | 17 | 16 | 19 | 18 | ||
D1 | 21 | 20 | 23 | 22 | |||
C3 | D0 | 25 | 24 | 27 | 26 | ||
D1 | 29 | 28 | 31 | 30 | |||
B1 | C0 | D0 | 33 | 32 | 35 | 34 | |
D1 | 37 | 36 | 39 | 38 | |||
C1 | D0 | 41 | 40 | 43 | 42 | ||
D1 | 45 | 44 | 47 | 46 | |||
C2 | D0 | 49 | 48 | 51 | 50 | ||
D1 | 53 | 52 | 55 | 54 | |||
C3 | D0 | 57 | 56 | 59 | 58 | ||
D1 | 61 | 60 | 63 | 62 | |||
A1 | B0 | C0 | D0 | 65 | 64 | 67 | 66 |
D1 | 69 | 68 | 71 | 70 | |||
C1 | D0 | 73 | 72 | 75 | 74 | ||
D1 | 77 | 76 | 79 | 78 | |||
C2 | D0 | 81 | 80 | 83 | 82 | ||
D1 | 85 | 84 | 87 | 86 | |||
C3 | D0 | 89 | 88 | 91 | 90 | ||
D1 | 93 | 92 | 95 | 94 | |||
B1 | C0 | D0 | 97 | 96 | 99 | 98 | |
D1 | 101 | 100 | 103 | 102 | |||
C1 | D0 | 105 | 104 | 107 | 106 | ||
D1 | 109 | 108 | 111 | 110 | |||
C2 | D0 | 113 | 112 | 115 | 114 | ||
D1 | 117 | 116 | 119 | 118 | |||
... | ... | ... | ... | ... | ... | ... | ... |
A2 | B0 | C1 | D0 | 137 | 136 | 139 | 138 |
D1 | 141 | 140 | 143 | 142 | |||
C2 | D0 | 145 | 144 | 147 | 146 | ||
D1 | 149 | 148 | 151 | 150 | |||
C3 | D0 | 153 | 152 | 155 | 154 | ||
D1 | 157 | 156 | 159 | 158 | |||
B1 | C0 | D0 | 161 | 160 | 163 | 162 | |
D1 | 165 | 164 | 167 | 166 | |||
C1 | D0 | 169 | 168 | 171 | 170 | ||
D1 | 173 | 172 | 175 | 174 | |||
C2 | D0 | 177 | 176 | 179 | 178 | ||
D1 | 181 | 180 | 183 | 182 | |||
C3 | D0 | 185 | 184 | 187 | 186 | ||
D1 | 189 | 188 | 191 | 190 | |||
A3 | B0 | C0 | D0 | 193 | 192 | 195 | 194 |
D1 | 197 | 196 | 199 | 198 | |||
C1 | D0 | 201 | 200 | 203 | 202 | ||
D1 | 205 | 204 | 207 | 206 | |||
C2 | D0 | 209 | 208 | 211 | 210 | ||
D1 | 213 | 212 | 215 | 214 | |||
C3 | D0 | 217 | 216 | 219 | 218 | ||
D1 | 221 | 220 | 223 | 222 | |||
B1 | C0 | D0 | 225 | 224 | 227 | 226 | |
D1 | 229 | 228 | 231 | 230 | |||
C1 | D0 | 233 | 232 | 235 | 234 | ||
D1 | 237 | 236 | 239 | 238 | |||
C2 | D0 | 241 | 240 | 243 | 242 | ||
D1 | 245 | 244 | 247 | 246 | |||
C3 | D0 | 249 | 248 | 251 | 250 | ||
D1 | 253 | 252 | 255 | 254 |
64 rows × 4 columns
# Basic multi-index slicing using slices, lists, and labels.
dfmi.loc[(slice('A1','A3'), slice(None), ['C1', 'C3']), :] # slice('A1','A3') 相当于 ['A1':'A3']
# dfmi.loc[(slice('A1','A3'), slice(None), ['C1', 'C3']) :] # 错误 冒号前面必须有逗号
# Basic multi-index slicing using slices, lists, and labels.
dfmi.loc[(slice('A1','A3'), slice(None), ['C1', 'C3']), :] # slice('A1','A3') 相当于 ['A1':'A3']
# dfmi.loc[(slice('A1','A3'), slice(None), ['C1', 'C3']) :] # 错误 冒号前面必须有逗号
lvl0 | a | b | |||||
lvl1 | bar | foo | bah | foo | |||
A1 | B0 | C1 | D0 | 73 | 72 | 75 | 74 |
D1 | 77 | 76 | 79 | 78 | |||
C3 | D0 | 89 | 88 | 91 | 90 | ||
D1 | 93 | 92 | 95 | 94 | |||
B1 | C1 | D0 | 105 | 104 | 107 | 106 | |
D1 | 109 | 108 | 111 | 110 | |||
C3 | D0 | 121 | 120 | 123 | 122 | ||
D1 | 125 | 124 | 127 | 126 | |||
A2 | B0 | C1 | D0 | 137 | 136 | 139 | 138 |
D1 | 141 | 140 | 143 | 142 | |||
C3 | D0 | 153 | 152 | 155 | 154 | ||
D1 | 157 | 156 | 159 | 158 | |||
B1 | C1 | D0 | 169 | 168 | 171 | 170 | |
D1 | 173 | 172 | 175 | 174 | |||
C3 | D0 | 185 | 184 | 187 | 186 | ||
D1 | 189 | 188 | 191 | 190 | |||
A3 | B0 | C1 | D0 | 201 | 200 | 203 | 202 |
D1 | 205 | 204 | 207 | 206 | |||
C3 | D0 | 217 | 216 | 219 | 218 | ||
D1 | 221 | 220 | 223 | 222 | |||
B1 | C1 | D0 | 233 | 232 | 235 | 234 | |
D1 | 237 | 236 | 239 | 238 | |||
C3 | D0 | 249 | 248 | 251 | 250 | ||
D1 | 253 | 252 | 255 | 254 |
# You can use a pd.IndexSlice to have a more natural syntax using :
# rather than using slice(None)
# 使用pd.IndexSlice 可以用冒号 : 代替 slice(None)
idx = pd.IndexSlice
dfmi.loc[idx[:, :, ['C1', 'C3']], idx[:, 'foo']] # 默认必须是一个元组()来指定关键字,而且全选的话只能使用slice(None)
# You can use a pd.IndexSlice to have a more natural syntax using :
# rather than using slice(None)
# 使用pd.IndexSlice 可以用冒号 : 代替 slice(None)
idx = pd.IndexSlice
dfmi.loc[idx[:, :, ['C1', 'C3']], idx[:, 'foo']] # 默认必须是一个元组()来指定关键字,而且全选的话只能使用slice(None)
lvl0 | a | b | |||
lvl1 | foo | foo | |||
A0 | B0 | C1 | D0 | 8 | 10 |
D1 | 12 | 14 | |||
C3 | D0 | 24 | 26 | ||
D1 | 28 | 30 | |||
B1 | C1 | D0 | 40 | 42 | |
D1 | 44 | 46 | |||
C3 | D0 | 56 | 58 | ||
D1 | 60 | 62 | |||
A1 | B0 | C1 | D0 | 72 | 74 |
D1 | 76 | 78 | |||
C3 | D0 | 88 | 90 | ||
D1 | 92 | 94 | |||
B1 | C1 | D0 | 104 | 106 | |
D1 | 108 | 110 | |||
C3 | D0 | 120 | 122 | ||
D1 | 124 | 126 | |||
A2 | B0 | C1 | D0 | 136 | 138 |
D1 | 140 | 142 | |||
C3 | D0 | 152 | 154 | ||
D1 | 156 | 158 | |||
B1 | C1 | D0 | 168 | 170 | |
D1 | 172 | 174 | |||
C3 | D0 | 184 | 186 | ||
D1 | 188 | 190 | |||
A3 | B0 | C1 | D0 | 200 | 202 |
D1 | 204 | 206 | |||
C3 | D0 | 216 | 218 | ||
D1 | 220 | 222 | |||
B1 | C1 | D0 | 232 | 234 | |
D1 | 236 | 238 | |||
C3 | D0 | 248 | 250 | ||
D1 | 252 | 254 |
# 一次执行复杂选取
dfmi.loc['A1', (slice(None), 'foo')]
# 一次执行复杂选取
dfmi.loc['A1', (slice(None), 'foo')]
lvl0 | a | b | ||
lvl1 | foo | foo | ||
B0 | C0 | D0 | 64 | 66 |
D1 | 68 | 70 | ||
C1 | D0 | 72 | 74 | |
D1 | 76 | 78 | ||
C2 | D0 | 80 | 82 | |
D1 | 84 | 86 | ||
C3 | D0 | 88 | 90 | |
D1 | 92 | 94 | ||
B1 | C0 | D0 | 96 | 98 |
D1 | 100 | 102 | ||
C1 | D0 | 104 | 106 | |
D1 | 108 | 110 | ||
C2 | D0 | 112 | 114 | |
D1 | 116 | 118 | ||
C3 | D0 | 120 | 122 | |
D1 | 124 | 126 |
dfmi.loc[idx[:, :, ['C1', 'C3']], idx[:, 'foo']]
dfmi.loc[idx[:, :, ['C1', 'C3']], idx[:, 'foo']]
lvl0 | a | b | |||
lvl1 | foo | foo | |||
A0 | B0 | C1 | D0 | 8 | 10 |
D1 | 12 | 14 | |||
C3 | D0 | 24 | 26 | ||
D1 | 28 | 30 | |||
B1 | C1 | D0 | 40 | 42 | |
D1 | 44 | 46 | |||
C3 | D0 | 56 | 58 | ||
D1 | 60 | 62 | |||
A1 | B0 | C1 | D0 | 72 | 74 |
D1 | 76 | 78 | |||
C3 | D0 | 88 | 90 | ||
D1 | 92 | 94 | |||
B1 | C1 | D0 | 104 | 106 | |
D1 | 108 | 110 | |||
C3 | D0 | 120 | 122 | ||
D1 | 124 | 126 | |||
A2 | B0 | C1 | D0 | 136 | 138 |
D1 | 140 | 142 | |||
C3 | D0 | 152 | 154 | ||
D1 | 156 | 158 | |||
B1 | C1 | D0 | 168 | 170 | |
D1 | 172 | 174 | |||
C3 | D0 | 184 | 186 | ||
D1 | 188 | 190 | |||
A3 | B0 | C1 | D0 | 200 | 202 |
D1 | 204 | 206 | |||
C3 | D0 | 216 | 218 | ||
D1 | 220 | 222 | |||
B1 | C1 | D0 | 232 | 234 | |
D1 | 236 | 238 | |||
C3 | D0 | 248 | 250 | ||
D1 | 252 | 254 |
# Using a boolean indexer you can provide selection related to the values.
# 使用布尔索引
mask = dfmi[('a', 'foo')] > 200
mask
dfmi.loc[idx[mask, :, ['C1', 'C3']], idx[:, 'foo']]
# Using a boolean indexer you can provide selection related to the values.
# 使用布尔索引
mask = dfmi[('a', 'foo')] > 200
mask
dfmi.loc[idx[mask, :, ['C1', 'C3']], idx[:, 'foo']]
A0 B0 C0 D0 False
D1 False
C1 D0 False
D1 False
C2 D0 False
D1 False
C3 D0 False
D1 False
B1 C0 D0 False
D1 False
C1 D0 False
D1 False
C2 D0 False
D1 False
C3 D0 False
D1 False
A1 B0 C0 D0 False
D1 False
C1 D0 False
D1 False
C2 D0 False
D1 False
C3 D0 False
D1 False
B1 C0 D0 False
D1 False
C1 D0 False
D1 False
C2 D0 False
D1 False
...
A2 B0 C1 D0 False
D1 False
C2 D0 False
D1 False
C3 D0 False
D1 False
B1 C0 D0 False
D1 False
C1 D0 False
D1 False
C2 D0 False
D1 False
C3 D0 False
D1 False
A3 B0 C0 D0 False
D1 False
C1 D0 False
D1 True
C2 D0 True
D1 True
C3 D0 True
D1 True
B1 C0 D0 True
D1 True
C1 D0 True
D1 True
C2 D0 True
D1 True
C3 D0 True
D1 True
Name: (a, foo), Length: 64, dtype: bool
lvl0 | a | b | |||
lvl1 | foo | foo | |||
A3 | B0 | C1 | D1 | 204 | 206 |
C3 | D0 | 216 | 218 | ||
D1 | 220 | 222 | |||
B1 | C1 | D0 | 232 | 234 | |
D1 | 236 | 238 | |||
C3 | D0 | 248 | 250 | ||
D1 | 252 | 254 |
# 指定轴参数axis,说明传入的切片在一个轴上
dfmi.loc(axis=0)[:, :, ['C1', 'C3']]
# 指定轴参数axis,说明传入的切片在一个轴上
dfmi.loc(axis=0)[:, :, ['C1', 'C3']]
lvl0 | a | b | |||||
lvl1 | bar | foo | bah | foo | |||
A0 | B0 | C1 | D0 | 9 | 8 | 11 | 10 |
D1 | 13 | 12 | 15 | 14 | |||
C3 | D0 | 25 | 24 | 27 | 26 | ||
D1 | 29 | 28 | 31 | 30 | |||
B1 | C1 | D0 | 41 | 40 | 43 | 42 | |
D1 | 45 | 44 | 47 | 46 | |||
C3 | D0 | 57 | 56 | 59 | 58 | ||
D1 | 61 | 60 | 63 | 62 | |||
A1 | B0 | C1 | D0 | 73 | 72 | 75 | 74 |
D1 | 77 | 76 | 79 | 78 | |||
C3 | D0 | 89 | 88 | 91 | 90 | ||
D1 | 93 | 92 | 95 | 94 | |||
B1 | C1 | D0 | 105 | 104 | 107 | 106 | |
D1 | 109 | 108 | 111 | 110 | |||
C3 | D0 | 121 | 120 | 123 | 122 | ||
D1 | 125 | 124 | 127 | 126 | |||
A2 | B0 | C1 | D0 | 137 | 136 | 139 | 138 |
D1 | 141 | 140 | 143 | 142 | |||
C3 | D0 | 153 | 152 | 155 | 154 | ||
D1 | 157 | 156 | 159 | 158 | |||
B1 | C1 | D0 | 169 | 168 | 171 | 170 | |
D1 | 173 | 172 | 175 | 174 | |||
C3 | D0 | 185 | 184 | 187 | 186 | ||
D1 | 189 | 188 | 191 | 190 | |||
A3 | B0 | C1 | D0 | 201 | 200 | 203 | 202 |
D1 | 205 | 204 | 207 | 206 | |||
C3 | D0 | 217 | 216 | 219 | 218 | ||
D1 | 221 | 220 | 223 | 222 | |||
B1 | C1 | D0 | 233 | 232 | 235 | 234 | |
D1 | 237 | 236 | 239 | 238 | |||
C3 | D0 | 249 | 248 | 251 | 250 | ||
D1 | 253 | 252 | 255 | 254 |
# 可以使用这种指定轴方向的方式赋值
df2 = dfmi.copy()
df2.loc(axis=0)[:, :, ['C1', 'C3']] = -10
df2
# 可以使用这种指定轴方向的方式赋值
df2 = dfmi.copy()
df2.loc(axis=0)[:, :, ['C1', 'C3']] = -10
df2
lvl0 | a | b | |||||
lvl1 | bar | foo | bah | foo | |||
A0 | B0 | C0 | D0 | 1 | 0 | 3 | 2 |
D1 | 5 | 4 | 7 | 6 | |||
C1 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
C2 | D0 | 17 | 16 | 19 | 18 | ||
D1 | 21 | 20 | 23 | 22 | |||
C3 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
B1 | C0 | D0 | 33 | 32 | 35 | 34 | |
D1 | 37 | 36 | 39 | 38 | |||
C1 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
C2 | D0 | 49 | 48 | 51 | 50 | ||
D1 | 53 | 52 | 55 | 54 | |||
C3 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
A1 | B0 | C0 | D0 | 65 | 64 | 67 | 66 |
D1 | 69 | 68 | 71 | 70 | |||
C1 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
C2 | D0 | 81 | 80 | 83 | 82 | ||
D1 | 85 | 84 | 87 | 86 | |||
C3 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
B1 | C0 | D0 | 97 | 96 | 99 | 98 | |
D1 | 101 | 100 | 103 | 102 | |||
C1 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
C2 | D0 | 113 | 112 | 115 | 114 | ||
D1 | 117 | 116 | 119 | 118 | |||
... | ... | ... | ... | ... | ... | ... | ... |
A2 | B0 | C1 | D0 | -10 | -10 | -10 | -10 |
D1 | -10 | -10 | -10 | -10 | |||
C2 | D0 | 145 | 144 | 147 | 146 | ||
D1 | 149 | 148 | 151 | 150 | |||
C3 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
B1 | C0 | D0 | 161 | 160 | 163 | 162 | |
D1 | 165 | 164 | 167 | 166 | |||
C1 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
C2 | D0 | 177 | 176 | 179 | 178 | ||
D1 | 181 | 180 | 183 | 182 | |||
C3 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
A3 | B0 | C0 | D0 | 193 | 192 | 195 | 194 |
D1 | 197 | 196 | 199 | 198 | |||
C1 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
C2 | D0 | 209 | 208 | 211 | 210 | ||
D1 | 213 | 212 | 215 | 214 | |||
C3 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
B1 | C0 | D0 | 225 | 224 | 227 | 226 | |
D1 | 229 | 228 | 231 | 230 | |||
C1 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 | |||
C2 | D0 | 241 | 240 | 243 | 242 | ||
D1 | 245 | 244 | 247 | 246 | |||
C3 | D0 | -10 | -10 | -10 | -10 | ||
D1 | -10 | -10 | -10 | -10 |
64 rows × 4 columns
# You can use a right-hand-side of an alignable object as well.
# 可以在右侧使用可定位的对象?
df2 = dfmi.copy()
df2.loc[idx[:, :, ['C1', 'C3']], :] = df2 * 1000
df2
# You can use a right-hand-side of an alignable object as well.
# 可以在右侧使用可定位的对象?
df2 = dfmi.copy()
df2.loc[idx[:, :, ['C1', 'C3']], :] = df2 * 1000
df2
lvl0 | a | b | |||||
lvl1 | bar | foo | bah | foo | |||
A0 | B0 | C0 | D0 | 1 | 0 | 3 | 2 |
D1 | 5 | 4 | 7 | 6 | |||
C1 | D0 | 9000 | 8000 | 11000 | 10000 | ||
D1 | 13000 | 12000 | 15000 | 14000 | |||
C2 | D0 | 17 | 16 | 19 | 18 | ||
D1 | 21 | 20 | 23 | 22 | |||
C3 | D0 | 25000 | 24000 | 27000 | 26000 | ||
D1 | 29000 | 28000 | 31000 | 30000 | |||
B1 | C0 | D0 | 33 | 32 | 35 | 34 | |
D1 | 37 | 36 | 39 | 38 | |||
C1 | D0 | 41000 | 40000 | 43000 | 42000 | ||
D1 | 45000 | 44000 | 47000 | 46000 | |||
C2 | D0 | 49 | 48 | 51 | 50 | ||
D1 | 53 | 52 | 55 | 54 | |||
C3 | D0 | 57000 | 56000 | 59000 | 58000 | ||
D1 | 61000 | 60000 | 63000 | 62000 | |||
A1 | B0 | C0 | D0 | 65 | 64 | 67 | 66 |
D1 | 69 | 68 | 71 | 70 | |||
C1 | D0 | 73000 | 72000 | 75000 | 74000 | ||
D1 | 77000 | 76000 | 79000 | 78000 | |||
C2 | D0 | 81 | 80 | 83 | 82 | ||
D1 | 85 | 84 | 87 | 86 | |||
C3 | D0 | 89000 | 88000 | 91000 | 90000 | ||
D1 | 93000 | 92000 | 95000 | 94000 | |||
B1 | C0 | D0 | 97 | 96 | 99 | 98 | |
D1 | 101 | 100 | 103 | 102 | |||
C1 | D0 | 105000 | 104000 | 107000 | 106000 | ||
D1 | 109000 | 108000 | 111000 | 110000 | |||
C2 | D0 | 113 | 112 | 115 | 114 | ||
D1 | 117 | 116 | 119 | 118 | |||
... | ... | ... | ... | ... | ... | ... | ... |
A2 | B0 | C1 | D0 | 137000 | 136000 | 139000 | 138000 |
D1 | 141000 | 140000 | 143000 | 142000 | |||
C2 | D0 | 145 | 144 | 147 | 146 | ||
D1 | 149 | 148 | 151 | 150 | |||
C3 | D0 | 153000 | 152000 | 155000 | 154000 | ||
D1 | 157000 | 156000 | 159000 | 158000 | |||
B1 | C0 | D0 | 161 | 160 | 163 | 162 | |
D1 | 165 | 164 | 167 | 166 | |||
C1 | D0 | 169000 | 168000 | 171000 | 170000 | ||
D1 | 173000 | 172000 | 175000 | 174000 | |||
C2 | D0 | 177 | 176 | 179 | 178 | ||
D1 | 181 | 180 | 183 | 182 | |||
C3 | D0 | 185000 | 184000 | 187000 | 186000 | ||
D1 | 189000 | 188000 | 191000 | 190000 | |||
A3 | B0 | C0 | D0 | 193 | 192 | 195 | 194 |
D1 | 197 | 196 | 199 | 198 | |||
C1 | D0 | 201000 | 200000 | 203000 | 202000 | ||
D1 | 205000 | 204000 | 207000 | 206000 | |||
C2 | D0 | 209 | 208 | 211 | 210 | ||
D1 | 213 | 212 | 215 | 214 | |||
C3 | D0 | 217000 | 216000 | 219000 | 218000 | ||
D1 | 221000 | 220000 | 223000 | 222000 | |||
B1 | C0 | D0 | 225 | 224 | 227 | 226 | |
D1 | 229 | 228 | 231 | 230 | |||
C1 | D0 | 233000 | 232000 | 235000 | 234000 | ||
D1 | 237000 | 236000 | 239000 | 238000 | |||
C2 | D0 | 241 | 240 | 243 | 242 | ||
D1 | 245 | 244 | 247 | 246 | |||
C3 | D0 | 249000 | 248000 | 251000 | 250000 | ||
D1 | 253000 | 252000 | 255000 | 254000 |
64 rows × 4 columns
# Cross-section 断面
# xs 方法 另外提供了一个级别level参数 用来选择多重索引中的部分级别
# xs 当提供轴参数时,也可用于列的选择
df
# Cross-section 断面
# xs 方法 另外提供了一个级别level参数 用来选择多重索引中的部分级别
# xs 当提供轴参数时,也可用于列的选择
df
A | B | C | ||
first | second | |||
bar | one | -1.608162 | 1.207609 | -0.369463 |
two | -0.007312 | -0.272366 | 1.862253 | |
baz | one | 1.048244 | -0.530191 | -0.118297 |
two | -0.029907 | -0.689641 | -0.148326 | |
foo | one | -0.437866 | -0.244362 | 1.147616 |
two | -1.853398 | -1.476252 | -1.389965 | |
qux | one | 2.026875 | 0.818493 | 0.817716 |
two | 0.359521 | 0.353771 | 0.787394 |
df.xs("one", level="second")
df.loc[(slice(None), "one"), :] # 使用切片得到同样的选择
df.xs("one", level="second")
df.loc[(slice(None), "one"), :] # 使用切片得到同样的选择
A | B | C | |
first | |||
bar | -1.608162 | 1.207609 | -0.369463 |
baz | 1.048244 | -0.530191 | -0.118297 |
foo | -0.437866 | -0.244362 | 1.147616 |
qux | 2.026875 | 0.818493 | 0.817716 |
A | B | C | ||
first | second | |||
bar | one | -1.608162 | 1.207609 | -0.369463 |
baz | one | 1.048244 | -0.530191 | -0.118297 |
foo | one | -0.437866 | -0.244362 | 1.147616 |
qux | one | 2.026875 | 0.818493 | 0.817716 |
df = df.T
df.xs('one', level='second', axis=1) # 在列方向选择
df.loc[:, (slice(None),'one')] # 使用切片方式
df = df.T
df.xs('one', level='second', axis=1) # 在列方向选择
df.loc[:, (slice(None),'one')] # 使用切片方式
first | bar | baz | foo | qux |
A | -1.608162 | 1.048244 | -0.437866 | 2.026875 |
B | 1.207609 | -0.530191 | -0.244362 | 0.818493 |
C | -0.369463 | -0.118297 | 1.147616 | 0.817716 |
first | bar | baz | foo | qux |
second | one | one | one | one |
A | -1.608162 | 1.048244 | -0.437866 | 2.026875 |
B | 1.207609 | -0.530191 | -0.244362 | 0.818493 |
C | -0.369463 | -0.118297 | 1.147616 | 0.817716 |
# xs 方法使用多重关键字keys,关键字元组
df.xs(('one', 'bar'), level=('second', 'first'), axis=1) # 关键字元组可以与级层顺序不一致,与给定level顺序一致
df.loc[:, ("bar", "one")]
# df.loc[:, ("one", "bar")] # 错误,元组元素的顺序与级层顺序一致
# xs 方法使用多重关键字keys,关键字元组
df.xs(('one', 'bar'), level=('second', 'first'), axis=1) # 关键字元组可以与级层顺序不一致,与给定level顺序一致
df.loc[:, ("bar", "one")]
# df.loc[:, ("one", "bar")] # 错误,元组元素的顺序与级层顺序一致
first | bar |
second | one |
A | -1.608162 |
B | 1.207609 |
C | -0.369463 |
A -1.608162
B 1.207609
C -0.369463
Name: (bar, one), dtype: float64
# drop_level=False 参数可以使xs保留选定的层级,而不是舍弃,这样的话,与切片得到的结果完全相同
df.xs('one', level='second', axis=1, drop_level=False) # 默认 drop_level=True
df.loc[:, (slice(None) ,"one")]
# drop_level=False 参数可以使xs保留选定的层级,而不是舍弃,这样的话,与切片得到的结果完全相同
df.xs('one', level='second', axis=1, drop_level=False) # 默认 drop_level=True
df.loc[:, (slice(None) ,"one")]
first | bar | baz | foo | qux |
second | one | one | one | one |
A | -1.608162 | 1.048244 | -0.437866 | 2.026875 |
B | 1.207609 | -0.530191 | -0.244362 | 0.818493 |
C | -0.369463 | -0.118297 | 1.147616 | 0.817716 |
first | bar | baz | foo | qux |
second | one | one | one | one |
A | -1.608162 | 1.048244 | -0.437866 | 2.026875 |
B | 1.207609 | -0.530191 | -0.244362 | 0.818493 |
C | -0.369463 | -0.118297 | 1.147616 | 0.817716 |
# Advanced reindexing and alignment 高级索引和定位
# level参数加在索引reindex和定位align方法中。可用于通过级层进行广播值。
midx = pd.MultiIndex(levels=[['zero', 'one'], ['x','y']],
labels=[[1,1,0,0],[1,0,1,0]]) # 指定了labels,指定了层级间对应关系
midx
# Advanced reindexing and alignment 高级索引和定位
# level参数加在索引reindex和定位align方法中。可用于通过级层进行广播值。
midx = pd.MultiIndex(levels=[['zero', 'one'], ['x','y']],
labels=[[1,1,0,0],[1,0,1,0]]) # 指定了labels,指定了层级间对应关系
midx
MultiIndex(levels=[['zero', 'one'], ['x', 'y']],
labels=[[1, 1, 0, 0], [1, 0, 1, 0]])
df = pd.DataFrame(np.random.randn(4,2), index=midx)
df
df = pd.DataFrame(np.random.randn(4,2), index=midx)
df
0 | 1 | ||
one | y | -1.388542 | -1.170054 |
x | 0.240534 | -0.656707 | |
zero | y | -0.848351 | -1.394871 |
x | -0.212248 | 0.051445 |
# 不同层级索引的广播计算
df2 = df.mean(level=1)
df2
df2 = df.mean(level=0)
df2
# 不同层级索引的广播计算
df2 = df.mean(level=1)
df2
df2 = df.mean(level=0)
df2
0 | 1 | |
y | -1.118447 | -1.282462 |
x | 0.014143 | -0.302631 |
0 | 1 | |
one | -0.574004 | -0.913381 |
zero | -0.530300 | -0.671713 |
# 重构索引
df2.reindex(df.index, level=0)
# 重构索引
df2.reindex(df.index, level=0)
0 | 1 | ||
one | y | -0.574004 | -0.913381 |
x | -0.574004 | -0.913381 | |
zero | y | -0.530300 | -0.671713 |
x | -0.530300 | -0.671713 |
# 定位/对齐
df
df2
df.align(df2, level=0)
df_aligned, df2_aligned = df.align(df2, level=0) # ??
df_aligned
df2_aligned
# 定位/对齐
df
df2
df.align(df2, level=0)
df_aligned, df2_aligned = df.align(df2, level=0) # ??
df_aligned
df2_aligned
0 | 1 | ||
one | y | -1.388542 | -1.170054 |
x | 0.240534 | -0.656707 | |
zero | y | -0.848351 | -1.394871 |
x | -0.212248 | 0.051445 |
0 | 1 | |
one | -0.574004 | -0.913381 |
zero | -0.530300 | -0.671713 |
( 0 1
one y -1.388542 -1.170054
x 0.240534 -0.656707
zero y -0.848351 -1.394871
x -0.212248 0.051445, 0 1
one y -0.574004 -0.913381
x -0.574004 -0.913381
zero y -0.530300 -0.671713
x -0.530300 -0.671713)
0 | 1 | ||
one | y | -1.388542 | -1.170054 |
x | 0.240534 | -0.656707 | |
zero | y | -0.848351 | -1.394871 |
x | -0.212248 | 0.051445 |
0 | 1 | ||
one | y | -0.574004 | -0.913381 |
x | -0.574004 | -0.913381 | |
zero | y | -0.530300 | -0.671713 |
x | -0.530300 | -0.671713 |
# 交换层级 swaplevel()
df.swaplevel(0, 1, axis=0)
# 交换层级 swaplevel()
df.swaplevel(0, 1, axis=0)
0 | 1 | ||
y | one | -1.388542 | -1.170054 |
x | one | 0.240534 | -0.656707 |
y | zero | -0.848351 | -1.394871 |
x | zero | -0.212248 | 0.051445 |
# reorder_levels 概况了 swaplevel 函数, 可以一步交换层级索引
df.reorder_levels([1,0], axis=0) # 看上去结果与swaplevel一样,传入参数不一样
# reorder_levels 概况了 swaplevel 函数, 可以一步交换层级索引
df.reorder_levels([1,0], axis=0) # 看上去结果与swaplevel一样,传入参数不一样
0 | 1 | ||
y | one | -1.388542 | -1.170054 |
x | one | 0.240534 | -0.656707 |
y | zero | -0.848351 | -1.394871 |
x | zero | -0.212248 | 0.051445 |
# 多重索引排序
# 排序是为了搞笑的索引和切片。任何索引都可以使用sort_index
tuples
s = pd.Series(np.random.randn(8), index=pd.MultiIndex.from_tuples(tuples))
s
# 多重索引排序
# 排序是为了搞笑的索引和切片。任何索引都可以使用sort_index
tuples
s = pd.Series(np.random.randn(8), index=pd.MultiIndex.from_tuples(tuples))
s
[('baz', 'two'),
('qux', 'two'),
('bar', 'one'),
('foo', 'one'),
('qux', 'one'),
('baz', 'one'),
('foo', 'two'),
('bar', 'two')]
baz two 1.365155
qux two -1.331225
bar one -1.512430
foo one 0.468294
qux one -0.667115
baz one -0.502417
foo two 1.685553
bar two -1.611271
dtype: float64
s.sort_index()
s.sort_index(level=1) # 默认是level=0排序
s.sort_index(level=0)
s.sort_index()
s.sort_index(level=1) # 默认是level=0排序
s.sort_index(level=0)
bar one -1.512430
two -1.611271
baz one -0.502417
two 1.365155
foo one 0.468294
two 1.685553
qux one -0.667115
two -1.331225
dtype: float64
bar one -1.512430
baz one -0.502417
foo one 0.468294
qux one -0.667115
bar two -1.611271
baz two 1.365155
foo two 1.685553
qux two -1.331225
dtype: float64
bar one -1.512430
two -1.611271
baz one -0.502417
two 1.365155
foo one 0.468294
two 1.685553
qux one -0.667115
two -1.331225
dtype: float64
# level参数除了可以用整型序号,还可以使用层级的names
s.index.set_names(['L1', 'L2'], inplace=True)
s
s.sort_index(level="L1")
s.sort_index(level="L2")
# level参数除了可以用整型序号,还可以使用层级的names
s.index.set_names(['L1', 'L2'], inplace=True)
s
s.sort_index(level="L1")
s.sort_index(level="L2")
L1 L2
baz two 1.365155
qux two -1.331225
bar one -1.512430
foo one 0.468294
qux one -0.667115
baz one -0.502417
foo two 1.685553
bar two -1.611271
dtype: float64
L1 L2
bar one -1.512430
two -1.611271
baz one -0.502417
two 1.365155
foo one 0.468294
two 1.685553
qux one -0.667115
two -1.331225
dtype: float64
L1 L2
bar one -1.512430
baz one -0.502417
foo one 0.468294
qux one -0.667115
bar two -1.611271
baz two 1.365155
foo two 1.685553
qux two -1.331225
dtype: float64
# 可以指定排序的轴方向
df.T
df.T.sort_index(level=1, axis=1)
# 可以指定排序的轴方向
df.T
df.T.sort_index(level=1, axis=1)
one | zero | |||
y | x | y | x | |
0 | -1.388542 | 0.240534 | -0.848351 | -0.212248 |
1 | -1.170054 | -0.656707 | -1.394871 | 0.051445 |
zero | one | zero | one | |
x | x | y | y | |
0 | -0.212248 | 0.240534 | -0.848351 | -1.388542 |
1 | 0.051445 | -0.656707 | -1.394871 | -1.170054 |
# 即使数据没有排序也可以索引,但是这样效率低下。
# 返回值是拷贝
dfm = pd.DataFrame({'jim': [0, 0, 1, 1],
'joe': ['x', 'x', 'z', 'y'],
'jolie': np.random.rand(4)})
dfm
# 即使数据没有排序也可以索引,但是这样效率低下。
# 返回值是拷贝
dfm = pd.DataFrame({'jim': [0, 0, 1, 1],
'joe': ['x', 'x', 'z', 'y'],
'jolie': np.random.rand(4)})
dfm
jim | joe | jolie | |
0 | 0 | x | 0.844228 |
1 | 0 | x | 0.317508 |
2 | 1 | z | 0.413824 |
3 | 1 | y | 0.074264 |
dfm = dfm.set_index(["jim", "joe"])
dfm
dfm = dfm.set_index(["jim", "joe"])
dfm
jolie | ||
jim | joe | |
0 | x | 0.844228 |
x | 0.317508 | |
1 | z | 0.413824 |
y | 0.074264 |
dfm.loc[(1, "z")] # 会提示PerformanceWarning
dfm.loc[(1, "z")] # 会提示PerformanceWarning
d:\python\36-64\lib\site-packages\ipykernel_launcher.py:1: PerformanceWarning: indexing past lexsort depth may impact performance.
"""Entry point for launching an IPython kernel.
jolie | ||
jim | joe | |
1 | z | 0.413824 |
# dfm.loc[(0,'y'):(1, 'z')] # 错误 无法定位
dfm.index.is_lexsorted()
dfm.index.lexsort_depth
# dfm.loc[(0,'y'):(1, 'z')] # 错误 无法定位
dfm.index.is_lexsorted()
dfm.index.lexsort_depth
False
1
dfm = dfm.sort_index() # 索引排序,默认对所有层级
dfm
dfm = dfm.sort_index() # 索引排序,默认对所有层级
dfm
jolie | ||
jim | joe | |
0 | x | 0.844228 |
x | 0.317508 | |
1 | y | 0.074264 |
z | 0.413824 |
dfm.index.is_lexsorted()
dfm.index.lexsort_depth
dfm.loc[(0,'y'):(1, 'z')]
dfm.index.is_lexsorted()
dfm.index.lexsort_depth
dfm.loc[(0,'y'):(1, 'z')]
True
2
jolie | ||
jim | joe | |
1 | y | 0.074264 |
z | 0.413824 |
# Take Methods take 方法 (拿、取)
# 与numpy的数组类似,padas的index、series、Dataframe也提供take方法
# 用来检索给定轴方向上给定的指数indices(必须是整数列表或者整数数组,可以是负整数)
# 在性能方面,由于take方法管理了一个更窄的输入范围,它能提供比想象的索引更快的性能
index = pd.Index(np.random.randint(0, 1000, 10))
index
# Take Methods take 方法 (拿、取)
# 与numpy的数组类似,padas的index、series、Dataframe也提供take方法
# 用来检索给定轴方向上给定的指数indices(必须是整数列表或者整数数组,可以是负整数)
# 在性能方面,由于take方法管理了一个更窄的输入范围,它能提供比想象的索引更快的性能
index = pd.Index(np.random.randint(0, 1000, 10))
index
Int64Index([523, 532, 386, 998, 832, 71, 965, 274, 389, 59], dtype='int64')
positions = [0, 9, 3]
index[positions]
index.take(positions)
positions = [0, 9, 3]
index[positions]
index.take(positions)
Int64Index([523, 59, 998], dtype='int64')
Int64Index([523, 59, 998], dtype='int64')
ser = pd.Series(np.random.randn(10))
ser
ser = pd.Series(np.random.randn(10))
ser
0 0.733196
1 0.975773
2 -0.261602
3 -0.055134
4 0.959253
5 1.189025
6 -0.434102
7 0.653628
8 0.248894
9 -0.203562
dtype: float64
ser.iloc[positions]
ser.take(positions)
ser.iloc[positions]
ser.take(positions)
0 0.733196
9 -0.203562
3 -0.055134
dtype: float64
0 0.733196
9 -0.203562
3 -0.055134
dtype: float64
# 对DataFrame,indices应该是一个一维 的列表或数组,规定了行或列的位置
frm = pd.DataFrame(np.random.randn(5, 3))
frm
# 对DataFrame,indices应该是一个一维 的列表或数组,规定了行或列的位置
frm = pd.DataFrame(np.random.randn(5, 3))
frm
0 | 1 | 2 | |
0 | -0.722107 | -1.758271 | 0.580805 |
1 | 0.555332 | -0.856173 | -1.143862 |
2 | -0.636994 | 1.312340 | 0.046131 |
3 | -0.154813 | 0.311931 | 0.933192 |
4 | -1.277001 | -0.144097 | -1.871135 |
frm.take([1, 4, 3]) # 默认取行方向
frm.take([0, 2], axis=1)
frm.take([1, 4, 3]) # 默认取行方向
frm.take([0, 2], axis=1)
0 | 1 | 2 | |
1 | 0.555332 | -0.856173 | -1.143862 |
4 | -1.277001 | -0.144097 | -1.871135 |
3 | -0.154813 | 0.311931 | 0.933192 |
0 | 2 | |
0 | -0.722107 | 0.580805 |
1 | 0.555332 | -1.143862 |
2 | -0.636994 | 0.046131 |
3 | -0.154813 | 0.933192 |
4 | -1.277001 | -1.871135 |
# 注意:take方法不要用于布尔indices
arr = np.random.randn(10)
arr
# 注意:take方法不要用于布尔indices
arr = np.random.randn(10)
arr
array([-0.00772525, 0.95419469, 1.80636718, -2.46742236, -0.025503 ,
0.44203691, 0.48626739, -0.74160374, -0.22453771, 0.8813933 ])
arr.take([False, False, True, True]) # 相当于取了[0,0,1,1]
arr[[0, 1]]
arr.take([False, False, True, True]) # 相当于取了[0,0,1,1]
arr[[0, 1]]
array([-0.00772525, -0.00772525, 0.95419469, 0.95419469])
array([-0.00772525, 0.95419469])
ser = pd.Series(np.random.randn(10))
ser
ser = pd.Series(np.random.randn(10))
ser
0 1.782426
1 0.531882
2 -0.339277
3 0.500497
4 -0.333816
5 -1.713753
6 -0.125252
7 -0.857100
8 0.385080
9 1.247962
dtype: float64
ser.take([False, False, True, True]) # 相当于取了[0,0,1,1]
ser.iloc[[0, 1]]
ser.take([False, False, True, True]) # 相当于取了[0,0,1,1]
ser.iloc[[0, 1]]
0 1.782426
0 1.782426
1 0.531882
1 0.531882
dtype: float64
0 1.782426
1 0.531882
dtype: float64
# Index Types 索引 index 对象
# 其他一些索引对象
# Index Types 索引 index 对象
# 其他一些索引对象
# CategoricalIndex 绝对索引?类别索引?
# 用于支持重复的索引
from pandas.api.types import CategoricalDtype
# CategoricalIndex 绝对索引?类别索引?
# 用于支持重复的索引
from pandas.api.types import CategoricalDtype
df = pd.DataFrame({'A': np.arange(6),
'B': list('aabbca')})
df
df = pd.DataFrame({'A': np.arange(6),
'B': list('aabbca')})
df
A | B | |
0 | 0 | a |
1 | 1 | a |
2 | 2 | b |
3 | 3 | b |
4 | 4 | c |
5 | 5 | a |
df['B'] = df['B'].astype(CategoricalDtype(list('cab')))
df
df.dtypes
df.B.cat.categories
df['B'] = df['B'].astype(CategoricalDtype(list('cab')))
df
df.dtypes
df.B.cat.categories
A | B | |
0 | 0 | a |
1 | 1 | a |
2 | 2 | b |
3 | 3 | b |
4 | 4 | c |
5 | 5 | a |
A int32
B category
dtype: object
Index(['c', 'a', 'b'], dtype='object')
df2 = df.set_index('B')
df2
df2.index
df2 = df.set_index('B')
df2
df2.index
A | |
B | |
a | 0 |
a | 1 |
b | 2 |
b | 3 |
c | 4 |
a | 5 |
CategoricalIndex(['a', 'a', 'b', 'b', 'c', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
# 使用 __getitem__/.iloc/.loc 索引时,索引对象 必须 在类别里面,否则操作将挂起
df2.loc['a']
df2.loc['a'].index # 保留了全部的 CategoricalIndex
df2.sort_index() # 按照categoies给定的顺序排序
# 使用 __getitem__/.iloc/.loc 索引时,索引对象 必须 在类别里面,否则操作将挂起
df2.loc['a']
df2.loc['a'].index # 保留了全部的 CategoricalIndex
df2.sort_index() # 按照categoies给定的顺序排序
A | |
B | |
a | 0 |
a | 1 |
a | 5 |
CategoricalIndex(['a', 'a', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
A | |
B | |
c | 4 |
a | 0 |
a | 1 |
a | 5 |
b | 2 |
b | 3 |
df2.groupby(level=0)
df2.groupby(level=0).sum()
df2.groupby(level=0).sum().index # 也保留了category
df2.groupby(level=0)
df2.groupby(level=0).sum()
df2.groupby(level=0).sum().index # 也保留了category
<pandas.core.groupby.DataFrameGroupBy object at 0x00000000117AC710>
A | |
B | |
c | 4 |
a | 6 |
b | 5 |
CategoricalIndex(['c', 'a', 'b'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
df2.reindex(['a','e']) # reindex 传入普通列表 返回一个 普通的 index
df2.reindex(['a','e']).index
df2.reindex(pd.Categorical(['a','e'],categories=list('abcde'))) # 指定catgorical index,即使原来的index没有的类别,也可以reindex
df2.reindex(pd.Categorical(['a','e'],categories=list('abcde'))).index
df2.reindex(['a','e']) # reindex 传入普通列表 返回一个 普通的 index
df2.reindex(['a','e']).index
df2.reindex(pd.Categorical(['a','e'],categories=list('abcde'))) # 指定catgorical index,即使原来的index没有的类别,也可以reindex
df2.reindex(pd.Categorical(['a','e'],categories=list('abcde'))).index
A | |
B | |
a | 0.0 |
a | 1.0 |
a | 5.0 |
e | NaN |
Index(['a', 'a', 'a', 'e'], dtype='object', name='B')
A | |
B | |
a | 0.0 |
a | 1.0 |
a | 5.0 |
e | NaN |
CategoricalIndex(['a', 'a', 'a', 'e'], categories=['a', 'b', 'c', 'd', 'e'], ordered=False, name='B', dtype='category')
# 注意:变形和比较操作必须有同样的categories,否则报错
# 注意:变形和比较操作必须有同样的categories,否则报错
# Int64Index and RangeIndex
# Int64Index 是pandas基础索引。
# RangeIndex是Int64Index的一个子集,现在作为所有NDFrame对象的默认索引。
# Int64Index and RangeIndex
# Int64Index 是pandas基础索引。
# RangeIndex是Int64Index的一个子集,现在作为所有NDFrame对象的默认索引。
# Float64Index 当创建索引index时,传入浮点数或者浮点与整数混合值,就默认是Float64Index
indexf = pd.Index([1.5, 2, 3, 4.5, 5])
indexf
# Float64Index 当创建索引index时,传入浮点数或者浮点与整数混合值,就默认是Float64Index
indexf = pd.Index([1.5, 2, 3, 4.5, 5])
indexf
Float64Index([1.5, 2.0, 3.0, 4.5, 5.0], dtype='float64')
sf = pd.Series(range(5), index=indexf)
sf
sf = pd.Series(range(5), index=indexf)
sf
1.5 0
2.0 1
3.0 2
4.5 3
5.0 4
dtype: int64
# [] .loc 基于 label,整数将被转为浮点值
sf[1.5:4.5]
sf[1:4]
sf.loc[3] # label,不是位置索引
# sf[3.2] # 错误,传入值必须在labels中
# [] .loc 基于 label,整数将被转为浮点值
sf[1.5:4.5]
sf[1:4]
sf.loc[3] # label,不是位置索引
# sf[3.2] # 错误,传入值必须在labels中
1.5 0
2.0 1
3.0 2
4.5 3
dtype: int64
1.5 0
2.0 1
3.0 2
dtype: int64
2
sf.iloc[3] # 基于位置,传入整数,不能传入浮点数
sf.iloc[3] # 基于位置,传入整数,不能传入浮点数
3
# 例子: 有不规则的数据表,其索引类似时间间隔,但数值是浮点型的
dfir1 = pd.DataFrame(np.random.randn(5,2),
index=np.arange(5) * 250.0,
columns=list('AB'))
dfir1
dfir2 = pd.DataFrame(np.random.randn(6,2),
index=np.arange(4,10) * 250.1,
columns=list('AB'))
dfir2
dfir = pd.concat([dfir1,dfir2])
dfir
# 例子: 有不规则的数据表,其索引类似时间间隔,但数值是浮点型的
dfir1 = pd.DataFrame(np.random.randn(5,2),
index=np.arange(5) * 250.0,
columns=list('AB'))
dfir1
dfir2 = pd.DataFrame(np.random.randn(6,2),
index=np.arange(4,10) * 250.1,
columns=list('AB'))
dfir2
dfir = pd.concat([dfir1,dfir2])
dfir
A | B | |
0.0 | 1.158461 | 0.595743 |
250.0 | 1.457556 | 0.268541 |
500.0 | -0.437650 | -0.299700 |
750.0 | -1.095812 | -2.079684 |
1000.0 | 0.242220 | -0.868812 |
A | B | |
1000.4 | -0.858327 | -0.364968 |
1250.5 | -1.445806 | -2.129608 |
1500.6 | 0.799049 | 1.232102 |
1750.7 | -1.132538 | 0.283472 |
2000.8 | -1.157884 | 0.398119 |
2250.9 | -1.330821 | -0.563333 |
A | B | |
0.0 | 1.158461 | 0.595743 |
250.0 | 1.457556 | 0.268541 |
500.0 | -0.437650 | -0.299700 |
750.0 | -1.095812 | -2.079684 |
1000.0 | 0.242220 | -0.868812 |
1000.4 | -0.858327 | -0.364968 |
1250.5 | -1.445806 | -2.129608 |
1500.6 | 0.799049 | 1.232102 |
1750.7 | -1.132538 | 0.283472 |
2000.8 | -1.157884 | 0.398119 |
2250.9 | -1.330821 | -0.563333 |
# 选取第1秒前的数据
dfir[:1000]
# 选取第1秒前的数据
dfir[:1000]
A | B | |
0.0 | 1.158461 | 0.595743 |
250.0 | 1.457556 | 0.268541 |
500.0 | -0.437650 | -0.299700 |
750.0 | -1.095812 | -2.079684 |
1000.0 | 0.242220 | -0.868812 |
# IntervalIndex 区间索引 (数学上的开闭区间)
df = pd.DataFrame({'A': [1, 2, 3, 4]},
index=pd.IntervalIndex.from_breaks([0, 1, 2, 3, 4]))
df
# IntervalIndex 区间索引 (数学上的开闭区间)
df = pd.DataFrame({'A': [1, 2, 3, 4]},
index=pd.IntervalIndex.from_breaks([0, 1, 2, 3, 4]))
df
A | |
(0, 1] | 1 |
(1, 2] | 2 |
(2, 3] | 3 |
(3, 4] | 4 |
df.loc[2] # loc 可以是区间的边缘
df.loc[2.5]
df.loc[1.5:2.5]
df.loc[2] # loc 可以是区间的边缘
df.loc[2.5]
df.loc[1.5:2.5]
A 2
Name: (1, 2], dtype: int64
A 3
Name: (2, 3], dtype: int64
A | |
(1, 2] | 2 |
(2, 3] | 3 |
# Interval and IntervalIndex are used by cut and qcut
# 区间数值类型和区间类型索引可以使用 cut qcut 方法??
c = pd.cut(range(4), bins=2)
c
c.categories
# Interval and IntervalIndex are used by cut and qcut
# 区间数值类型和区间类型索引可以使用 cut qcut 方法??
c = pd.cut(range(4), bins=2)
c
c.categories
[(-0.003, 1.5], (-0.003, 1.5], (1.5, 3.0], (1.5, 3.0]]
Categories (2, interval[float64]): [(-0.003, 1.5] < (1.5, 3.0]]
IntervalIndex([(-0.003, 1.5], (1.5, 3.0]]
closed='right',
dtype='interval[float64]')
pd.cut([0, 3, 5, 1], bins=c.categories) # 允许一个interval类型去bin(分隔)其他数据
pd.cut([0, 3, 5, 1], bins=c.categories) # 允许一个interval类型去bin(分隔)其他数据
[(-0.003, 1.5], (1.5, 3.0], NaN, (-0.003, 1.5]]
Categories (2, interval[float64]): [(-0.003, 1.5] < (1.5, 3.0]]
# Miscellaneous indexing FAQ 杂项 常见问题
# Miscellaneous indexing FAQ 杂项 常见问题
# Integer indexing 整数型索引
# 整型的索引是label,应满足label的要求
# 在pandas中,一般认为标签label事项大于整数定位。
s = pd.Series(range(5))
s
# s[-1] # 异常
# s.loc[-1] # 异常
s.loc[-1:] # 允许
s.iloc[-1] # 允许
df = pd.DataFrame(np.random.randn(5, 4))
df
df.loc[-2:]
# df.loc[-2] # 异常
# Integer indexing 整数型索引
# 整型的索引是label,应满足label的要求
# 在pandas中,一般认为标签label事项大于整数定位。
s = pd.Series(range(5))
s
# s[-1] # 异常
# s.loc[-1] # 异常
s.loc[-1:] # 允许
s.iloc[-1] # 允许
df = pd.DataFrame(np.random.randn(5, 4))
df
df.loc[-2:]
# df.loc[-2] # 异常
0 0
1 1
2 2
3 3
4 4
dtype: int64
0 0
1 1
2 2
3 3
4 4
dtype: int64
4
0 | 1 | 2 | 3 | |
0 | 0.021033 | 0.127054 | -0.864734 | -1.835828 |
1 | -0.400611 | 0.594981 | -1.758866 | -1.059539 |
2 | -0.108597 | 0.784000 | 0.306035 | -0.695933 |
3 | -0.078048 | -1.742895 | -0.159740 | 0.934115 |
4 | -0.524633 | 0.433224 | -0.732334 | 0.442827 |
0 | 1 | 2 | 3 | |
0 | 0.021033 | 0.127054 | -0.864734 | -1.835828 |
1 | -0.400611 | 0.594981 | -1.758866 | -1.059539 |
2 | -0.108597 | 0.784000 | 0.306035 | -0.695933 |
3 | -0.078048 | -1.742895 | -0.159740 | 0.934115 |
4 | -0.524633 | 0.433224 | -0.732334 | 0.442827 |
# Non-monotonic indexes require exact matches 非单调索引要求精确匹配
# 如果series或Dataframe的索引是单调增或单调减的,则基于标签的切片可以超出索引的范围。
# 就像对一般python列表list的索引切片。
# 可以用is_monotonic_increasing和is_monotonic_decreasing测试单调属性
df = pd.DataFrame(index=[2,3,3,4,5], columns=['data'], data=list(range(5)))
df
# Non-monotonic indexes require exact matches 非单调索引要求精确匹配
# 如果series或Dataframe的索引是单调增或单调减的,则基于标签的切片可以超出索引的范围。
# 就像对一般python列表list的索引切片。
# 可以用is_monotonic_increasing和is_monotonic_decreasing测试单调属性
df = pd.DataFrame(index=[2,3,3,4,5], columns=['data'], data=list(range(5)))
df
data | |
2 | 0 |
3 | 1 |
3 | 2 |
4 | 3 |
5 | 4 |
df.index.is_monotonic_increasing
df.index.is_monotonic_decreasing
df.index.is_monotonic_increasing
df.index.is_monotonic_decreasing
True
False
df.loc[0:4, :] # 没有0和1行,但是返回了label为2、3、4的行
df.loc[13:15, :] # 超出界限,返回空
df.loc[0:4, :] # 没有0和1行,但是返回了label为2、3、4的行
df.loc[13:15, :] # 超出界限,返回空
data | |
2 | 0 |
3 | 1 |
3 | 2 |
4 | 3 |
# 非单调索引,切片必须在index内,而且边界的值必须是唯一的
df = pd.DataFrame(index=[2,3,1,4,3,5], columns=['data'], data=list(range(6)))
df
df.index.is_monotonic_increasing
# 非单调索引,切片必须在index内,而且边界的值必须是唯一的
df = pd.DataFrame(index=[2,3,1,4,3,5], columns=['data'], data=list(range(6)))
df
df.index.is_monotonic_increasing
data | |
2 | 0 |
3 | 1 |
1 | 2 |
4 | 3 |
3 | 4 |
5 | 5 |
False
df.loc[2:4, :]
# df.loc[0:4, :] # 错误没有0标签
# df.loc[2:3, :] # 错误,边界标签3不是唯一的
df.loc[2:4, :]
# df.loc[0:4, :] # 错误没有0标签
# df.loc[2:3, :] # 错误,边界标签3不是唯一的
data | |
2 | 0 |
3 | 1 |
1 | 2 |
4 | 3 |
# Index.is_monotonic_increasing() and Index.is_monotonic_decreasing() 只检测弱单调(可以有重复值)
# 结合使用 Index.is_unique() 可以检测严格单调性
weakly_monotonic = pd.Index(['a', 'b', 'c', 'c'])
weakly_monotonic
weakly_monotonic.is_monotonic_increasing
weakly_monotonic.is_monotonic_increasing & weakly_monotonic.is_unique
# Index.is_monotonic_increasing() and Index.is_monotonic_decreasing() 只检测弱单调(可以有重复值)
# 结合使用 Index.is_unique() 可以检测严格单调性
weakly_monotonic = pd.Index(['a', 'b', 'c', 'c'])
weakly_monotonic
weakly_monotonic.is_monotonic_increasing
weakly_monotonic.is_monotonic_increasing & weakly_monotonic.is_unique
Index(['a', 'b', 'c', 'c'], dtype='object')
True
False
# Endpoints are inclusive 端点(边界)包括在内
# 与标准的python切片(不包括右端点值)相比,pandas中的标签切片包含端点值。
# 主要原因是经常不可能轻易断定 在索引的局部标签后 的 后继或者下一个元素
# Endpoints are inclusive 端点(边界)包括在内
# 与标准的python切片(不包括右端点值)相比,pandas中的标签切片包含端点值。
# 主要原因是经常不可能轻易断定 在索引的局部标签后 的 后继或者下一个元素
s = pd.Series(np.random.randn(6), index=list('abcdef'))
s
s = pd.Series(np.random.randn(6), index=list('abcdef'))
s
a 1.280483
b 1.562738
c 0.904503
d -0.470785
e -0.008048
f -0.413812
dtype: float64
s[2:5] # 基于整型的索引,与既有标签的不同,不包括右端点
s[2:5] # 基于整型的索引,与既有标签的不同,不包括右端点
c 0.904503
d -0.470785
e -0.008048
dtype: float64
# 如果用标签,不容易取得下一个标签
# s.loc['c':'e'+1] # 错误
s.loc['c':'e']
# 如果用标签,不容易取得下一个标签
# s.loc['c':'e'+1] # 错误
s.loc['c':'e']
c 0.904503
d -0.470785
e -0.008048
dtype: float64
# Indexing potentially changes underlying Series dtype
# 在series类型下索引可能出现变化
# The different indexing operation can potentially change the dtype of a Series.
# 不同的索引操作可能会潜在的改变series的类型
series1 = pd.Series([1, 2, 3])
series1.dtype # int
series1
res = series1.reindex([0, 4])
res.dtype # float
res
# Indexing potentially changes underlying Series dtype
# 在series类型下索引可能出现变化
# The different indexing operation can potentially change the dtype of a Series.
# 不同的索引操作可能会潜在的改变series的类型
series1 = pd.Series([1, 2, 3])
series1.dtype # int
series1
res = series1.reindex([0, 4])
res.dtype # float
res
dtype('int64')
0 1
1 2
2 3
dtype: int64
dtype('float64')
0 1.0
4 NaN
dtype: float64
series2 = pd.Series([True])
series2.dtype # 布尔类型
series2
res = series2.reindex_like(series1)
res.dtype # '0' 型 (空?)
res
series2 = pd.Series([True])
series2.dtype # 布尔类型
series2
res = series2.reindex_like(series1)
res.dtype # '0' 型 (空?)
res
dtype('bool')
0 True
dtype: bool
dtype('O')
0 True
1 NaN
2 NaN
dtype: object
# 由于默认插入NaN,引起了dtype的改变。
# 这会导致一些问题,当使用如 numpy.logical_and. 的np ufuncs 时
# 由于默认插入NaN,引起了dtype的改变。
# 这会导致一些问题,当使用如 numpy.logical_and. 的np ufuncs 时
# 2018-02-22
# 2018-02-22