这一章学过了之后,可以对数据做最最最最初步的处理,另外书上也有点小错误
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
df1 = pd.DataFrame({'data0':['b','b','a','c','a','a','b'],'data1':range(7)})
df2 = pd.DataFrame({'data0':['a','b','d'],'data2':range(3)})
df3 = pd.DataFrame({'data30':['b','b','a','c','a','a','b'],'data1':range(7)})
df4 = pd.DataFrame({'data40':['a','b','d'],'data2':range(3)})
df5 = pd.DataFrame({'key1':['foo','foo','bar'],'key2':['one','two,','one,'],'lval':[1,2,3]})
df6 = pd.DataFrame({'key1':['foo','foo','bar','bar'],'key2':['one','one,','one,','two'],'rval':[4,5,6,7]})
df7 = pd.DataFrame({'group_val':[3.5,7]},index=['a','b'])
print df7
#多对一、多对多合并
#默认使用重叠列名作为键值
print pd.merge(df1,df2)
#两个对象列名相同时的显式指定
print pd.merge(df1,df2,on='data0')
#两个对象列名不同时的显式指定
print pd.merge(df3,df4,left_on='data30',right_on='data40')
#默认情况下merge做的是inner连接,求连接键的交集,会删除键值不同项(c,d)
#可以设置outer,left,right
print pd.merge(df1,df2,how='right')
#多键值合并,传入键值列
print pd.merge(df5,df6,on=['key1','key2'],how='outer')
#不同对象出现相同列名
print pd.merge(df5,df6,on='key1')
print pd.merge(df5,df6,on='key1',suffixes=('_left','_right'))
#索引做键值
#df1的data0列和df7的索引进行合并
print pd.merge(df1,df7,left_on='data0',right_index=True)
#轴向连接
#ndarray绑定
arr = np.arange(12).reshape((3,4))
print np.concatenate([arr,arr],axis=1)
s1 = pd.Series([0,1],index=['a','b'])
s2 = pd.Series([2,3,4], index=['c','d','e'])
s3 = pd.Series([5,6], index=['f','g'])
s4 = pd.concat([s1*5,s3])
#直接拼接,默认在axis=0轴上,结果为Series
#keys参数区分参与链接的片段,axis=1时为列名
print pd.concat([s1,s2,s3],keys=['s1','s2','s3'])
#在axis=1上拼接,结果产生DataFrame
print pd.concat([s1,s2,s3],axis=1)
#concat默认是outer
print pd.concat([s1,s4],axis=1)
print pd.concat([s1,s4],axis=1,join='inner')
#指定索引,没有数据补全nan
print pd.concat([s1,s4],axis=1,join_axes=[['a','c','b','e']])
#合并重叠数据
a = pd.Series([np.nan,2.5,np.nan,3.5,4.5,np.nan],
index=['h','e','l','o','a','d'])
b = pd.Series(np.arange(len(a),dtype=np.float64),
index=['h','e','l','o','a','d'])
#if a中的值为空,返回b
#else 返回 a
print np.where(pd.isnull(a),b,a)
#用其他object的数据自动补全某object数据的缺失值
#书中例子是 b[:-2].combine_first(a[2:])
#看不出来哪里补全了
#用b相应的数据补全a的缺失
print a.combine_first(b)
#重塑层次化索引
#stack:将数据的列转化为行
#unstack:将数据的行转化为列
#unstack会在需要的情况下引入缺失,stack会自动忽略缺失,二者可逆
data = pd.DataFrame(np.arange(6).reshape((2,3)),
index=pd.Index(['ohio','colorad'],name='indexname'),
columns=pd.Index(['data1','data2','data3'],name='columnname'))
print data
result = data.stack()
print result
#默认情况下unstack和stack操作的是最内层
print result.unstack()
#显式指定操作axis=0轴
print result.unstack(0)
#unstack操作时,作为旋转轴的级别将会成为结果中的最低级别
df = pd.DataFrame({'left':result, 'right':result+5},
columns=pd.Index(['left','right'],name='side'))
print df
print df.unstack('indexname')
print df.unstack('columnname')
#数据转换
#Removing duplicates
data = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'],
'k2': [1, 1, 2, 3, 3, 4, 4]})
#删除重复行
print data.duplicated()
#print data.drop_duplicates()
#按条件删除重复项,默认保留第一个重复项,take_last=True保留最后一个重复项
data['v1'] = range(7)
print data.drop_duplicates(['k1'])
#Transforming Data Using a Function or Mapping
data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
'Pastrami', 'corned beef', 'Bacon',
'pastrami', 'honey ham', 'nova lox'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}
#根据映射规则meat_to_animal为数据data添加一列表示肉的来源
#map可以实现元素级转换
#lower()处理字母大小写
data['animal'] = data['food'].map(lambda x: meat_to_animal[x.lower()])
print data
# Replacing Values
#以下操作等价
data = pd.Series([1., -999., 2., -999., -1000., 3.])
data.replace(-999,np.nan)
data.replace([-999,-1000],np.nan)
data.replace([-999,-1000],[np.nan,0])
data.replace({-999:np.nan,-1000:0})
#renaming axis name
data = pd.DataFrame(np.arange(12).reshape((3, 4)),
index=['Ohio', 'Colorado', 'New York'],
columns=['one', 'two', 'three', 'four'])
data.index = data.index.map(str.upper)
print data.rename(index=str.title,columns=str.upper)
print data.rename(index={'OHIO':'INDIdddd'},
columns={'three':'dddddffff'})
#inplace 参数直接修改data值
data.rename(index={'OHIO':'INDIdddd'},
columns={'three':'ffff'},inplace=True)
print data
#Discretization and Binning
#离散化和面元划分
#1、已知边界划分
#将连续数据离散
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
#划分为区间段
bins = [18,25,35,60,100]
#返回值为一个特殊的Categorical对象
#第三版书中写错了
cats = pd.cut(ages,bins)
#包含一个表示不同分类名称的categories数组
print cats.categories
#包含一个为ages数据进行标号的codes属性
print cats.codes
group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
#设置类别名称
print pd.cut(ages,bins,labels=group_names)
#2、未知边界划分
#划分边界位置,但已知划分个数,cut会根据最大最小值计算等长面元,
#每个区间的长度相似,但区间内部元素个数不同
data = np.random.randint(20,size=20)
cat = pd.cut(data,4)
print pd.value_counts(cat)
#qcut,每个区间长度不同,但区间内部元素个数相似
cat2 = pd.qcut(data,4)
print pd.value_counts(cat2)
#Detecting and Filtering Outliers
np.random.seed(12345)
#正态分布
data = pd.DataFrame(np.random.randn(1000,4))
col = data[3]
#第3列中绝对值大于3
print col[np.abs(col)>3]
#返回任意包含绝对值大于3的行
print data[(np.abs(data)>3).any(1)]
#随机采样
#相当于对原数组进行随机重排列,(是伪随机,输入参数一定时得到的结果一样)
df = pd.DataFrame(np.arange(5*4).reshape(5,4))
sampler = np.random.permutation(5)
print df.take(sampler)
#哑变量 One-Hot-coding
df = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
'data1': range(6)})
#进行哑编码,新得到的列用key_ 命名
dummies = pd.get_dummies(df['key'],prefix='key')
#df[[]]表示第一列,和索引
print df[['data1']].join(dummies)
mnames = ['movie_id', 'title', 'genres']
movies = pd.read_table('/Users/lee/Desktop/ml/pydata-book/dataset/datasets/movielens/movies.dat',
sep='::',header=None,names=mnames,engine='python')
#下面两句是python语法,没懂
genre_iter = (set(x.split('|')) for x in movies.genres)
genres = sorted(set.union(*genre_iter))
#待处理数据结构复杂,所以重新构建需要的特指标
#从零开始构建指标
dummies = pd.DataFrame(np.zeros((len(movies),len(genres))),columns=genres)
#编码movie.genres
for i, gen in enumerate(movies.genres):
dummies.loc[i,gen.split('|')] = 1
movies_windic = movies.join(dummies.add_prefix('Genre_'))
#以上方法较慢,仅适用于小量数据
#数据量大时,利用DataFrame内部更低级的函数
#如get_dummies,cut
np.random.seed(12345)
values = np.random.rand(10)
values
bins = [0, 0.2, 0.4, 0.6, 0.8, 1]
pd.get_dummies(pd.cut(values, bins))
#字符串
val = 'a,b, guido'
#python处理字符串
#split为根据符号切分,不区分空格
#strip用于修建空格、换行符
pieces = [x.strip() for x in val.split(',')]
print pieces
#拼接,参数可以为列表或者元组
print '::::::::::'.join(pieces)
#子串定位
print 'gui' in val
print val.index(',')
#如果找不到,index发生异常,find返回-1,count返回0
print val.find(':')
print val.count(':')
print val.replace(',',':')
#正则表达式
import re
text = 'foo bar\t baz \tqux'
#\s空白符,+ 1到多次
regex = re.compile('\s+')
#拆分后结果
print regex.split(text)
#返回匹配到的值
print regex.findall(text)
text = """Dave dave@google.com
Steve ste_ve@gmail.com
Rob rob@gmail.com
Ryan ryan@yahoo.com
aaa @af.com
"""
# 正则表达式含义:[] 内部任意匹配1到多次后 @ 匹配一次[] 内部匹配1到多次 . 匹配一次 []内部匹配2到4次
#必须有[]@[].[]才能匹配成功 ([]表示中括号内部的内容)
# text最后一行的内容不符合条件
pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
#IGNORECASE 忽略大小写
regex = re.compile(pattern,flags=re.IGNORECASE)
print regex.findall(text)
#search 只返回第一个匹配成功的起始和结束为止
m = regex.search(text)
print m
print text[m.start():m.end()]
#match 只返回字符串开头匹配成功的结果
print regex.match(text)
# 将匹配到的位置替换为新串
print regex.sub('ddddddd',text)
#() 是为了提取匹配的字符串
pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex = re.compile(pattern,flags=re.IGNORECASE)
print regex.findall(text)
#sub访问匹配项中的分组 \1 \2 \3
print regex.sub(r'Username: \1, Domain: \2, Suffix: \3 \n',text)
data = pd.Series({'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com',
'Rob': 'rob@gmail.com', 'Wes': np.nan})
#contains 判断是否包含子串
#str是Series的属性
print data.str.contains('gma')
#书中所说的元素矢量化操作并不能实现
import json
db = json.load(open('/Users/lee/Desktop/ml/pydata-book/dataset/datasets/usda_food/database.json'))
nutrients = pd.DataFrame(db[0]['nutrients'])
info_keys = ['description','group','id','manufacturer']
info = pd.DataFrame(db,columns=info_keys)
print pd.value_counts(info.group)[:10]
#将所有食物的营养成分整合成一张大表
nutrients = []
#for循环之后nutrients是一个list,每一个元素是一个DataFrame
#每一个DataFrame包含当前id所有的营养信息
for rec in db:
fnuts = pd.DataFrame(rec['nutrients'])
fnuts['id'] = rec['id']
nutrients.append(fnuts)
#竖排nutrients list中的每个元素,
#nutrients变成DataFrame格式
nutrients = pd.concat(nutrients,ignore_index=True)
nutrients.drop_duplicates()
#重命名
col_mapping = {'description':'food',
'group':'fgroup'}
info = info.rename(colums=col_mapping,copy=False)
col_mapping2 = {'description':'nutrient',
'group':'nutgroup'}
nutrients = nutrients.rename(colums=col_mapping2,copy=False)
#用于分析的数据
ndata = pd.merge(nutrients,info,on='id',how='outer')
网友评论