Numpy&pandas(三)--pandas索引

import pandas as pd
import numpy as np
#以下所有代码都以此为基础

pandas索引

#重新索引Series
s = pd.Series([1, 3, 5, 6, 8], index=list('acefh'))
s.reindex(list('abcdefgh'))
#本来没有的index值为NaN

s.reindex(list('abcdefgh'), fill_value=0)
#将NaN替换成0

s.reindex(list('abcdefgh'), method='ffill')
#ffill是front fill向前填充,将前面的值带给NaN

#重新索引DataFrame
df = pd.DataFrame(np.random.randn(4, 6), index=list('ADFH'), columns=['one', 'two', 'three', 'four', 'five', 'six'])
df2 = df.reindex(index=list('ABCDEFGH'))
#之前没有的index也是一样的NaN,而且df2是df的副本,改变其中值不会改变df中的值

df.reindex(columns=['one', 'three', 'five', 'seven'])
#只要写出来的这几列值,新加的seven里的值全是NaN
df.reindex(columns=['one', 'three', 'five', 'seven'], fill_value=0)
#只要写出来的这几列值,新加的seven里的值全是0

# fill method 只对行有效,得到的结果为seven一列全是NaN
df.reindex(columns=['one', 'three', 'five', 'seven'], method='ffill')

df.reindex(index=list('ABCDEFGH'), method='ffill')
#向后填充,将后面的值放到NaN中

丢弃部分数据

df = pd.DataFrame(np.random.randn(4, 6), index=list('ABCD'), columns=['one', 'two', 'three', 'four', 'five', 'six'])
df.drop('A')
#丢弃A这一行

df2 = df.drop(['two', 'four'], axis=1)
#默认丢弃行,axis = 1丢弃列

# 数据拷贝
df.iloc[0, 0] = 100
#是数据的备份,改变其并不改变原数据

广播运算

df = pd.DataFrame(np.arange(12).reshape(4, 3), index=['one', 'two', 'three', 'four'], columns=list('ABC'))
df.loc['one']
#输入行,输出列

df - df.loc['one']
#每一行都减去第一行

函数应用

df = pd.DataFrame(np.arange(12).reshape(4, 3), index=['one', 'two', 'three', 'four'], columns=list('ABC'))
# 每一列作为一个 Series 作为参数传递给 lambda 函数,输出一个series
df.apply(lambda x: x.max() - x.min())

# 每一行作为一个 Series 作为参数传递给 lambda 函数,输出一个series
df.apply(lambda x: x.max() - x.min(), axis=1)

# 返回多个值组成的 Series
def min_max(x):
    return pd.Series([x.min(), x.max()], index=['min', 'max'])
df.apply(min_max, axis=1)

# applymap: 逐元素运算
df = pd.DataFrame(np.random.randn(4, 3), index=['one', 'two', 'three', 'four'], columns=list('ABC'))
formater = '{0:.02f}'.format
# formater = lambda x: '%.02f' % x取小数点后两位
df.applymap(formater)

排序和排名

df = pd.DataFrame(np.random.randint(1, 10, (4, 3)), index=list('ABCD'), columns=['one', 'two', 'three'])
df.sort_values(by='one')
#用one排序,默认从小到大(升序)

s = pd.Series([3, 6, 2, 6, 4])
s.rank()
#输出的是索引和对应的排名的Series


s.rank(method='first', ascending=False)
#先遇见的先排,降序

数据唯一性及成员资格

适用于Series

s = pd.Series(list('abbcdabacad'))
s.unique()
#输出不重复的值

s.value_counts()
输出值和对应的出现次数

s.isin(['a', 'b', 'c'])
#看是否出现在abc中,返回true/false

索引

  • 行索引
  • 列索引
  • 索引的分类
  • 重复索引的处理
s = pd.Series(np.random.rand(5), index=list('abcde'))
s.index
#输出行索引

s.index.name = 'alpha'
#设置索引的name

df = pd.DataFrame(np.random.randn(4, 3), columns=['one', 'two', 'three'])
df.index#输出行索引
df.columns#输出列索引
pd.*Index?

重复索引

s = pd.Series(np.arange(6), index=list('abcbda'))
s['a']
#输出两个a的索引

s['c']
#输出c的索引

s.index.is_unique
#看index是否为唯一的,输出true/false

s.index.unique()
#输出不重复的index

s.groupby(s.index).sum()
#按index分类并将其值加起来

层次化索引

可以使数据在一个轴上有多个索引级别。即可以用二维的数据表达更高维度的数据,使数据组织方式更清晰。它使用 pd.MultiIndex 类来表示。

层次化索引有什么作用?

比如我们在分析股票数据,我们的一级行索引可以是日期;二级行索引可以是股票代码,列索引可以是股票的交易量,开盘价,收盘价等等。这样我们就可以把多个股票放在同一个时间维度下进行考察和分析。

  • Series多层索引
a = [['a', 'a', 'a', 'b', 'b', 'c', 'c'], [1, 2, 3, 1, 2, 2, 3]]
tuples = list(zip(*a))
#前后一一对应形成元组[(a, 1),(a, 2)……]

index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
#将tuples设置为多重索引,并命名为first和second

s = pd.Series(np.random.randn(7), index=index)
#生成一个二重索引的Series,a的都合并到一起,bc同理

s.index
#输出的是multiindex的levels = abc和123
#labels = 0001122,0120112
#还有names

s.index.levels[0]
#输出第一层索引即abc

s.index.levels[1]
#输出第二层索引即123

s['b']
#输出第一层索引b下的第二层索引以及他们的值

s['b':'c']
#输出第一层索引bc下第二层索引以及他们的值

s[['b', 'a']]
#输出ba的索引结果

s['b', 1]
#输出对应的值

s[:, 2]
#输出第二层索引有2的所有第一层索引以及他们对应的值


  • DataFrame多层索引
df = pd.DataFrame(np.random.randint(1, 10, (4, 3)), 
                  index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], 
                  columns=[['one', 'one', 'two'], ['blue', 'red', 'blue']])
df.index.names = ['row-1', 'row-2']
df.columns.names = ['col-1', 'col-2']
df.loc['a']
#输出a对应的行第二层索引和列对应两层索引以及他们的值

type(df.loc['a'])
#a是DataFrame的类型

df.loc['a', 1]
#输出a和1对应的列两层索引以及他们的值

df.loc['a', 1].index
#输出列的两层索引
#levels = 【one,two】,【blue, red】
#labels = [001][010]
#names = col-1 col-2

  • 索引交换及排序
df2 = df.swaplevel('row-1', 'row-2')
#两个行索引交换位置

df2.sortlevel(0)
#对第一个索引进行排序

  • 按照索引级别进行统计
#这个df还是之前没改变行索引顺序的dataframe
df.sum(level=0)
#对行第一索引进行累加,行第二层索引就没了

df.sum(level=1)
#对行第二层索引进行累加,行第一索引就没了

df2.sum(level=0)
#df2是行索引调换位置之后的df
#和上面一样


  • 索引和列的转换
df = pd.DataFrame({
        'a': range(7),
        'b': range(7, 0, -1),
        'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'],
        'd': [0, 1, 2, 0, 1, 2, 3]
    })
df.set_index('c')
#将c设置为行索引

df2 = df.set_index(['c', 'd'])
#将cd设置为一个二层索引,c是第一层索引

df3 = df2.reset_index().sort_index('columns')
#reset设置为空就是将所有的行索引都清空,变回原来的列,再通过第一列排序

(df3 == df)
#都是相等的

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值