1. 创建多层行索引
(1) 隐式构造
-
最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组:
index = [['一班', '一班', '一班', '二班', '二班', '二班'], ['张三', '李四', '王五', '赵六', '田七', '孙八']]
data = np.random.randint(0,150, size=(6,6))
df = DataFrame(data=data, index=index, columns=columns)
-
Series也可以创建多层索引
index = [['一班', '一班', '一班', '二班', '二班', '二班'], ['张三', '李四', '王五', '赵六', '田七', '孙八']] data = np.random.randint(0,150, size=6) s = Series(data=data, index=index)
(2) 显示构造pd.MultiIndex
-
使用数组
index = pd.MultiIndex.from_arrays([['一班', '一班', '一班', '二班', '二班', '二班'], ['张三', '李四', '王五', '赵六', '田七', '孙八']]) columns = [['期中', '期中', '期中', '期末', '期末', '期末'], ['语文', '数学', '英语', '语文', '数学', '英语']] data = np.random.randint(0,150, size=(6,6)) df = DataFrame(data=data, index=index, columns=columns)
-
使用tuple
index = pd.MultiIndex.from_tuples([('一班', '张三'), ('一班', '李四'), ('一班', '王五'), ('二班', '赵六'), ('二班', '田七'), ('二班', '孙八')]) columns = [['期中', '期中', '期中', '期末', '期末', '期末'], ['语文', '数学', '英语', '语文', '数学', '英语']] data = np.random.randint(0,150, size=(6,6)) df = DataFrame(data=data, index=index, columns=columns)
-
使用product
最简单,推荐使用 ,有条件限制
index = pd.MultiIndex.from_arrays([['一班', '一班', '一班', '二班', '二班', '二班'], ['张三', '李四', '王五', '赵六', '田七', '孙八']]) columns = pd.MultiIndex.from_product([['期中', '期末'], ['语文', '数学', '英语']]) data = np.random.randint(0,150, size=(6,6)) df = DataFrame(data=data, index=index, columns=columns)
2. 多层列索引
除了行索引index,列索引columns也能用同样的方法创建多层索引
3. 多层索引对象的索引与切片操作
(1)Series的操作
【重要】对于Series来说,直接中括号[]与使用.loc()完全一样,推荐使用中括号索引和切片
索引
s['一班','张三']
s.loc['一班'].loc['张三']
s.loc['一班', '张三'] # 推荐写法
s.iloc[0] # 隐式索引, 直接从最内层开始索引,起始下标为0
s.iloc[[0]]
切片
s.loc['一班':]
s.iloc[0:4]
(2)DataFrame的操作
索引:
重要: 列索引使用[], 行索引需使用loc[]
注意在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须让二级索引变成一级索引后才能对其进行索引!
df['期中', '语文'] # 列索引
行多级索引的索引和切片操作
df.loc['一班', '张三']
切片:
df['一班': '二班']
df.loc['一班': ]
df.iloc[0:4] # 隐式行切片
4. 索引的堆(stack)
-
stack()
-
unstack()
把水平的列索引转化为行索引就叫做stack 反之叫做unstack
df.stack() # 默认level=-1表示对最里面那一层操作
df.stack(level=0) # 对最外层操作
df.unstack(fill_value=0)
【小技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里。
使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。
5. 聚合操作
【注意】
-
需要指定axis
-
axis=0, 操作每一列,行数被压缩
-
axis=1, 操作每一行,列数被压缩
df.sum(axis=0, level=0) # level等于哪一层,哪一层就保留下来,其他层就被聚合掉.
二.pandas的拼接操作
pandas的拼接分为两种:
-
级联:pd.concat, pd.append
-
合并:pd.merge
1. 使用pd.concat()级联
pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数:
numpy 级联: concatenate pandas级联: concat
1) 简单级联
和np.concatenate一样,优先增加行数(默认axis=0)
pd.concat((df1,df2), ignore_index=True) # ignore_index 选择忽略原索引,重新索引
pd.concat((df1,df2), keys=['df1', 'df2']) # keys 使用多层索引,默认axis=0
2) 不匹配级联
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
有3种连接方式:
-
外连接:补NaN(默认模式)
pd.concat((df1, df2), sort=True, join='outer')
-
内连接:只连接匹配的项
pd.concat((df1, df2), sort=True, join='inner')
-
连接指定轴 join_axes
pd.concat((df1, df2), sort=True, join_axes=[df1.columns]) # 只保留df1的列
join_axes=[df1.columns] 相当于左连接
join_axes=[df2.columns] 相当于右连接
axis=1 指定水平方向级联 还是垂直方向级联 (默认垂直)
3) 使用append()函数添加
函数append专门用于在后面添加, 只能追加行
ddd.append(ddd2)
2. 使用pd.merge()合并
merge与concat的区别在于,merge需要依据某一共的列来进行合并
注意每一列元素的顺序不要求一致
-
默认根据两者相同column名称的那一列作为key来进行合并
-
使用on指定哪一列为key,当有多个key相同时使用
pd.merge(df1, df2, on='name', suffixes=['df1', 'df2'])
-
两边的key都不相同时, 使用left_on和right_on指定左右两边的列作为key
pd.merge(df1, df2, left_on='name', right_on='名字')
-
当左边的列和右边的index相同的时候,使用left_on 和 right_index=True , 反之一样
pd.merge(df1, df2, left_on='age', right_index=True)
内合并与外合并
-
内合并:只保留两者都有的key对应的行(默认模式how='inner')
-
外合并 how='outer': 缺失补NaN
df1.merge(df2, left_on='name', right_on='名字', how='outer')
列冲突的解决
有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名