pandas层次化索引和拼接

一.pandas层次化索引

1. 创建多层行索引

(1) 隐式构造

  • 最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组:

index = [['一班', '一班', '一班', '二班', '二班', '二班'], ['张三', '李四', '王五', '赵六', '田七', '孙八']]

columns = [['期中', '期中', '期中', '期末', '期末', '期末'], ['语文', '数学', '英语', '语文', '数学', '英语']]

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指定冲突列名

df1.merge(df2, on='name', suffixes=['', '_df2']) # suffixes=自己指定后缀

posted @ 2019-11-24 11:15  Deaseyy  阅读(3165)  评论(0编辑  收藏  举报