# encoding:utf-8
# pandas 主要有两个对象 Series 和 DataFrame
# 特点就是运算索引和列名会自动对齐
# ==============Series=================
obj = Series(np.random.randn(5),index=list('bcda')) #新建 Series
obj = Series({'a':111,'b':2222,'c':3333}) # 通过字典新疆 Series
obj.values #返回np数组表示形式
obj.index #返回索引对象
obj['a'] / obj.a / obj[['a','b','c']] #获取单个/多个元素
obj[obj>0] #布尔数组过滤
obj*2 #标量乘法 广播
np.exp(obj) #应用数学
# ==================DataFrame=============
#--------1.创建---------
df=DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=['one','two','three','four']) # 新建 DataFrame 并指定 索引 和 列名
df=DataFrame({'one':[1,1,1],'two':[2,2,2],'three':[3,3,3]}) # 通过 字典 新建 DataFrame 索引为默认值
# 通过嵌套字典 新建 DataFrame对象,外层key作为列名,内层key 作为 索引
df=DataFrame({'one':{2001:1,2002:1},'two':{2001:2,2002:2},'three':{2001:3,2002:3}})
#--------2.查看信息--------
df.head() / df.head(10) #查看头部的几个数据
df.describe() # 查看统计描述信息
#--------3.获取数据,行,列,新增,删除--------
df['one'] / df.one #获取一整列 即 series
df[:2] #切片访问 行索引 显示前两行
df[df['one']>0] #布尔访问 选择行
df.loc[2001] #通过索引 获取一整行数据
df.loc[2001:2002,'one':'three'] /df.loc[[2001,2003],['one','three']] #通过索引和列名 获取指定的元素
df['five']={2001:5,2002:5} / df['state'] = df.two==2 # 新建列 增加列
del df['five'] / df.drop(['five']) # 删除列 del是在原有对象上面做更改,drop是返回新的对象
df.index / df.columns #返回 索引/列名 对象 索引和列名对象都是不可更改类型
df.index.name / df.columns.name #可以设置 inde和columns 的name属性
df.T #转置 行列互换
df.values # 以np形式返回 df中的数据
# --------4.重新索引--------
# Series 重新索引,对不上的值填充0/前项值填充/后向值填充 返回新对象
obj.reindex(list('abcdef'),fill_value=0/method='ffill'/'bfill')
df.reindex(index=list('abcdef'),columns=['one','two','three'],fill_value=0/method='ffill'/'bfill') # DataFrame 重新索引 返回新对象
#-------- 5.多个df 运算 广播--------
# DataFrame 算术相加运算 只计算两个df中重叠的值相加,非重叠区并集索引并填充nan/0
df1+df2 / df1.add(df2,fill_value=0)
df1.reindex(columns=df2.columns,fill_value=0) #使用df2的列名作为 df1的列名
df1.sub(obj) / df1.sub(obj,axis=0) #在列/行 上进行广播运算
# --------6.函数应用 Series级和元素级--------
f=lambda x:x.max()-x.min() / lambda x:Series([x.max(),x.min()],index=['max','min']) #定义lambda函数
df1.apply(f) / df1.apply(f,axis=1) # 计算列/行上的差值/最大、小值 Series级函数应用
f=lambda x:"%0.2f" %x / lambda x: round(x)
df1.applymap(f) # 元素级函数的应用
#--------7.排序 索引排序,值排序--------
# 排序 sort_index 对行列索引名进行排序
df1.sort_index() / df1.sort_index(axis=1,ascending=False) #按行/列 索引的名字排序 升序/降序
# 对 值进行排序
obj.order() #Series 中对值进行排序 其中里面的NAN值会排在末尾
df1.sort_values(by=['one','two']) # 按多个列的值进行排序
#--------8.排名--------
# 排名
df['rank']=df.two.rank(method='first'/'average'/'min'/'max') #排名 默认是average
# 允许重复值索引
df=DataFrame(np.arange(12).reshape(4,3),index=list('aab')) #如果一个索引对应多个值 则返回一个Series
# --------9.内置统计函数运算--------
df.index.is_unique # 判断是否唯一
df.sum() /df.sum(axis=1) #对列/行进行求和 返回结果 为单行/列
df.mean(axis=1,skipna=False) #不忽略空值 求均值
df.idxman() #返回最大/小值索引位置
df.cumsum() / df.cummax() / df.cummin() # 累计和/累计最大/小值 返回DataFrame
df.mode() # 返回众数 可能有多个值
df.pct_change # 返回百分数增长变化
pd.value_counts(df.one,sort=False) #返回 各个值出现的频率
counts=lambda x:pd.value_counts(x)
df.apply(counts).fillna(0) / df.apply(pd.value_counts) # 统计每列中 值的频率 未出现的值填充0
# ========================缺失数据处理=================================
inplace=True #在方法中加入 inplace=true 为修改原对象,不创建新对象
df.isnull() # 判断DataFrame的每个值是否为空,返回布尔DataFame
#--------1.滤除缺失数据--------
df.dropna() / df[df.notnull()] #丢弃任何含有nan的行
df.dropna(how='all') / df.dropna(how='all',axis=1) #丢弃全为NAN的行/列
df.dropna(thresh=3) #保留至少3个非空值的行,即一行中有>=3个非空值 就保留
#--------2.填充缺失数据--------
df.fillna(0) #所有nan填充为0
df.fillna({'one':0.5,'two':3}) #第1列的nan填充为0.5 第2列的nan填充为3
df.fillna({'one':df.one.mean(),'two':df.two.mode()[0]}) #第1列的nan填充为第1列的均值 第2列的nan填充为第2列的众数
df.fillna(method='ffill'/'bfill') / df.fillna(method='ffill',limit=2) # 使用前项/后项值 填充nan, 填充限制为2个 只填充前两个
# ========================层次化索引================================
#--------1.层次化索引--------
obj2=Series(np.random.randn(8),index=[list('aaabbbcc'),[1,2,3,1,2,3,1,2]]) #新建 Series 层次索引对象
obj2.index
obj2['a'] / obj2.loc[:,2] / obj2[:,2] #选取数据子集
obj2.unstack() / df.stack() #将层次索引解重塑到dataFrame,或将DataFrame 分组到层次索引
df=DataFrame(np.arange(16).reshape(4,4),index=[list('aabb'),list(map(int,list('1212')))],columns=[['one','one','two','two'],list(map(int,list('1212')))]) #新建 DataFrame 对象
df['one'].loc['a'] #选取数据子集,左上角 one,a
df.index.names=['key1','key2'] #给索引指定名字
df.columns.names=['n1','n2']
df.swaplevel('key1','key2') / df.swaplevel('n1','n2',axis=1) #交换索引顺序 内容不变
df1.sort_index(level=1) #根据2级索引名排序
#--------2.层次化汇总--------
df.sum(level='key1')
df.sum(level='n1',axis=1)
#--------3.使用DataFrame中的列作为行索引--------
frame=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]
})
frame.set_index(['c','d']) #使用DataFrame中的列作为行索引
frame.reset_index() #层次化索引转移到列
# 注意事项
ser=Series(np.arange(3.))
ser[-1] #创建 Series时默认是数字索引 ,这里会产生歧义,不知道使用数字索引还是位置索引
# ========================面板数据================================
import pandas_datareader.data as web
pdata=pd.Panel(dict((stk,web.get_data_yahoo(stk,'1/1/2009','6/1/2012')) for stk in ['AAPL','GOOG','MSFT']))
pdata=pdata.swapaxes('item','minor_axis')
pdata['Adj Close']
pdata.loc[:,'2012-05-01',:]
pdata.loc[:,'2012-05-01':,:].to_frame()
pdata.loc[:,'2012-05-01':,:].to_frame().to_panel()