深入浅出Pandas读书笔记
使你在Series和DataFrame中存储和处理更高维度的数据
# 按团队分组, 各团队中平均成绩及格的人数
df.groupby(['team', df.select_dtypes('number').mean(1)>60]).count()
# 在列上产生多级索引
df.groupby('team').agg([min, max])
MultiIndex
对象是Pandas标准Index的子类, 由他来表示多层索引业务. 可以将MultiIndex
视为一个元祖对序列, 其中每个元祖对都是唯一的
# 定义一个序列, 生成多级索引
arrays = [[1, 1, 2, 2], ['A', 'B']*2]
index = pd.MultiIndex.from_arrays(arrays, names=['class', 'team'])
index
'''
MultiIndex([(1, 'A'),
(1, 'B'),
(2, 'A'),
(2, 'B')],
names=['class', 'team'])
'''
使用pd.MultiIndex.from_tuples()将由元祖组成的序列转换为多层索引
arrays = [[1, 1, 2, 2], ['A', 'B']*2]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, name=['class', 'team'])
pd.Series(np.random.randn(4), index=index)
'''
class team
1 A 1.013703
B -1.184143
2 A 0.870257
B 0.893465
dtype: float64
'''
pd.MultiIndex.from_product()可以做笛卡尔积计算
_class = [1, 2]
team = ['A', 'B']
index = pd.MultiIndex.from_product([_class, team], names=['class', 'team'])
index
'''
MultiIndex([(1, 'A'),
(1, 'B'),
(2, 'A'),
(2, 'B')],
names=['class', 'team'])
'''
pd.MultiIndex.from_frame()可以将DataFrame的数据转为多层索引对象
df_i = pd.DataFrame([['1', 'A'], ['1', 'B'], ['2', 'B'], ['2', 'B']], columns=['class', 'name'])
index = pd.MultiIndex.from_frame(df_i)
index
index_arrays = [[1, 1, 2, 2,], ['男', '男', '女', '女']]
columns_arrays = [['2019', '2019', '2020', '2020'], ['上半年', '下半年']*2]
index = pd.MultiIndex.from_arrays(index_arrays, names=('班级', '性别'))
columns = pd.MultiIndex.from_arrays(columns_arrays, names=('年份', '学期'))
df = pd.DataFrame([[88, 99, 88, 99], [77, 88, 97, 98], [67, 89, 54, 78], [34, 67, 89, 54]],
columns=columns, index=index)
df
'''
年份 2019 2020
学期 上半年 下半年 上半年 下半年
班级 性别
1 男 88 99 88 99
男 77 88 97 98
2 女 67 89 54 78
女 34 67 89 54
'''
df.index
'''
MultiIndex([(1, '男'),
(1, '男'),
(2, '女'),
(2, '女')],
names=['班级', '性别'])
'''
MultiIndex([(1, '男'),
(1, '男'),
(2, '女'),
(2, '女')],
names=['班级', '性别'])
'''
MultiIndex([('2019', '上半年'),
('2019', '下半年'),
('2020', '上半年'),
('2020', '下半年')],
names=['年份', '学期'])
'''
df.index.names # FrozenList(['班级', '性别'])
df.columns.names # FrozenList(['年份', '学期'])
df.index.nlevels # 行层级数
df.index.levels # 行层级
df.columns.nlevels # 列层级数
df.columns.levels # 列层级
# 获取索引第二层内容
df.index.get_level_values(1)
# 获取列索引第一层内容
df.columns.get_level_values(0)
# 按索引名称取索引内容
df.index.get_level_values('班级')
df.columns.get_level_values('年份')
df.sort_values(by=['性别', ('2020', '下半年')])
df.index.reorder_levels([1, 0]) # 等级顺序, 互换
df.swaplevel() # 等同于上面
df.index.to_numpy() # 横撑一个笛卡尔积的元祖对序列
df.swaplevel()
df.index.droplevel(0) # 删除指定等级
df.loc[1]
df.loc[(1, '男')]
df[‘2020’] # 整个一级索引
df[(‘2020’, ‘上半年’)] # 指定二级索引
df[‘2020’][‘上半年’] # 同上
行列查询和单层索引一样, 指定层内容也用元祖表示. slice(None)
可以在元组中占位, 表示本层所有内容
df.loc[(1, '男'), '2020']
df.loc[:, (slice(None), '下半年')] # 只看下半年
df.loc[(slice(None), '女'), :] # 只看女生
df.loc[(1, slice(None)), :] # 只看1班
df.loc[:, ('2020', slice(None))] # 只看2020年数据
df[df[('2020', '上半年')] > 80]
若找的是level=0的数据, 不需要指定level, 找其他层需要传入level=第几层, 找columns, 需要指定axis=1
df.xs((1, '男')) # 1班男生
df.xs('2020', axis=1) # 2020年
df.xs('男', level=1) # 所有男生
df.xs(2) # 所有2班的数据