利用python进行数据分析笔记
2016-02-24 22:24
921 查看
pandas基础
索引
Series和DataFrame都是有索引的,索引的好处是快速定位,在涉及到两个Series或DataFrame时可以根据索引自动对齐,比如日期自动对齐,这样可以省去很多事。缺失值
pd.isnull(obj) obj.isnull()
将字典转成数据框,并赋予列名,索引
DataFrame(data, columns=['col1','col2','col3'...], index = ['i1','i2','i3'...])
查看列名
DataFrame.columns
查看索引
DataFrame.index
重建索引
obj.reindex(['a','b','c','d','e'...], fill_value=0] #按给出的索引顺序重新排序,而不是替换索引。如果索引没有值,就用0填充 #就地修改索引 data.index=data.index.map(str.upper)
列顺序重排(也是重建索引)
DataFrame.reindex[columns=['col1','col2','col3'...])` #也可以同时重建index和columns DataFrame.reindex[index=['a','b','c'...],columns=['col1','col2','col3'...])
重建索引的快捷键
DataFrame.ix[['a','b','c'...],['col1','col2','col3'...]]
重命名轴索引
data.rename(index=str.title,columns=str.upper) #修改某个索引和列名,可以通过传入字典 data.rename(index={’old_index':'new_index'}, columns={'old_col':'new_col'})
查看某一列
DataFrame['state'] 或 DataFrame.state
查看某一行
需要用到索引DataFrame.ix['index_name']
添加或删除一列
DataFrame['new_col_name'] = 'char_or_number' #删除行 DataFrame.drop(['index1','index2'...]) #删除列 DataFrame.drop(['col1','col2'...],axis=1) #或 del DataFrame['col1']
DataFrame选择子集
类型 | 说明 |
---|---|
obj[val] | 选择一列或多列 |
obj.ix[val] | 选择一行或多行 |
obj.ix[:,val] | 选择一列或多列 |
obj.ix[val1,val2] | 同时选择行和列 |
reindx | 对行和列重新索引 |
icol,irow | 根据整数位置选取单列或单行 |
get_value,set_value | 根据行标签和列标签选择单个值 |
obj[['a','b','c'...]] obj['b':'e']=5
针对dataframe
#选择多列 dataframe[['col1','col2'...]] #选择多行 dataframe[m:n] #条件筛选 dataframe[dataframe['col3'>5]] #选择子集 dataframe.ix[0:3,0:5]
dataframe和series的运算
会根据 index 和 columns 自动对齐然后进行运算,很方便啊方法 | 说明 |
---|---|
add | 加法 |
sub | 减法 |
div | 除法 |
mul | 乘法 |
#没有数据的地方用0填充空值 df1.add(df2,fill_value=0) # dataframe 与 series 的运算 dataframe - series 规则是: -------- -------- | | | | | | | | -------- | | | | | | v -------- #指定轴方向 dataframe.sub(series,axis=0) 规则是: -------- --- | | | | -----> | | | | | | | | | | | | -------- ---
apply函数
f=lambda x:x.max()-x.min() #默认对每一列应用 dataframe.apply(f) #如果需要对每一行分组应用 dataframe.apply(f,axis=1)
排序和排名
#默认根据index排序,axis = 1 则根据columns排序 dataframe.sort_index(axis=0, ascending=False) # 根据值排序 dataframe.sort_index(by=['col1','col2'...]) #排名,给出的是rank值 series.rank(ascending=False) #如果出现重复值,则取平均秩次 #在行或列上面的排名 dataframe.rank(axis=0)
描述性统计
方法 | 说明 |
---|---|
count | 计数 |
describe | 给出各列的常用统计量 |
min,max | 最大最小值 |
argmin,argmax | 最大最小值的索引位置(整数) |
idxmin,idxmax | 最大最小值的索引值 |
quantile | 计算样本分位数 |
sum,mean | 对列求和,均值 |
mediam | 中位数 |
mad | 根据平均值计算平均绝对离差 |
var,std | 方差,标准差 |
skew | 偏度(三阶矩) |
Kurt | 峰度(四阶矩) |
cumsum | 累积和 |
Cummins,cummax | 累计组大致和累计最小值 |
cumprod | 累计积 |
diff | 一阶差分 |
pct_change | 计算百分数变化 |
唯一值,值计数,成员资格
obj.unique() obj.value_count() obj.isin(['b','c'])
处理缺失值
# 过滤缺失值 # 只要有缺失值就丢弃这一行 dataframe.dropna() #要求全部为缺失才丢弃这一行 dataframe.dropna(how='all') # 根据列来判断 dataframe.dropna(how='all',axis=1) # 填充缺失值 #1.用0填充 df.fillna(0) #2.不同的列用不同的值填充 df.fillna({1:0.5, 3:-1}) #3.用均值填充 df.fillna(df.mean()) # 此时axis参数同前面,
将列转成行索引
df.set_index(['col1','col2'...])
数据清洗,重塑
合并数据集
# 取 df1,df2 都有的部分,丢弃没有的 # 默认是inner的连接方式 pd.merge(df1,df2, how='inner') #如果df1,df2的连接字段名不同,则需要特别指定 pd.merge(df1,df2,left_on='l_key',right_on='r_key') #其他的连接方式有 left,right, outer等。 # 如果dataframe是多重索引,根据多个键进行合并 pd.merge(left, right, on=['key1','key2'],how = 'outer') #合并后如果有重复的列名,需要添加后缀 pd.merge(left, right, on='key1', suffixes=('_left','_right'))
索引上的合并
#针对dataframe中的连接键不是列名,而是索引名的情况。 pd.merge(left, right, left_on = 'col_key', right_index=True) #即左边的key是列名,右边的key是index。 #多重索引 pd.merge(left, right, left_on=['key1','key2'], right_index=True)
dataframe的join方法
#实现按索引合并。 #其实这个join方法和数据库的join函数是以一样的理解 left.join(right, how='outer') #一次合并多个数据框 left.join([right1,right2],how='outer')
轴向连接(更常用)
连接:concatenation绑定:binding
堆叠:stacking
列上的连接
np.concatenation([df1,df2],axis=1) #np包 pd.concat([df1,df2], axis=1) #pd包 #和R语言中的 cbind 是一样的 #如果axis=0,则和 rbind 是一样的 #索引对齐,没有的就为空 # join='inner' 得到交集 pd.concat([df1,df2], axis=1, join='innner') # keys 参数,还没看明白 # ignore_index=True,如果只是简单的合并拼接而不考虑索引问题。 pd.concat([df1,df2],ignore_index=True)
合并重复数据
针对可能有索引全部或者部分重叠的两个数据集填充因为合并时索引赵成的缺失值
where函数
#where即if-else函数 np.where(isnull(a),b,a)
combine_first方法
#如果a中值为空,就用b中的值填补 a[:-2].combine_first(b[2:]) #combine_first函数即对数据打补丁,用df2的数据填充df1中的缺失值 df1.combine_first(df2)
重塑层次化索引
stact:将数据转为长格式,即列旋转为行unstack:转为宽格式,即将行旋转为列
result=data.stack() result.unstack()
长格式转为宽格式
pivoted = data.pivot('date','item','value') #前两个参数分别是行和列的索引名,最后一个参数则是用来填充dataframe的数据列的列名。如果忽略最后一个参数,得到的dataframe会带有层次化的列。
透视表
table = df.pivot_table(values=["Price","Quantity"], index=["Manager","Rep"], aggfunc=[np.sum,np.mean], margins=True)) #values:需要对哪些字段应用函数 #index:透视表的行索引(row) #columns:透视表的列索引(column) #aggfunc:应用什么函数 #fill_value:空值填充 #margins:添加汇总项 #然后可以对透视表进行筛选 table.query('Manager == ["Debra Henley"]') table.query('Status == ["pending","won"]')
移除重复数据
# 判断是否重复 data.duplicated()` #移除重复数据 data.drop_duplicated() #对指定列判断是否存在重复值,然后删除重复数据 data.drop_duplicated(['key1'])
交叉表
是一种用于计算分组频率的特殊透视表.注意,只对离散型的,分类型的,字符型的有用,连续型数据是不能计算频率这种东西的。
pd.crosstab(df.col1, df.col2, margins=True)
类似vlookup函数
利用函数或映射进行数据转换#1.首先定义一个字典 meat_to_animal={ 'bacon':'pig', 'pulled pork':'pig', 'honey ham':'cow' } #2.对某一列应用一个函数,或者字典,顺便根据这一列的结果创建新列 data['new_col']=data['food'].map(str.lower).map(meat_to_animal)
替换值
data.replace(-999,np.na) #多个值的替换 data.replace([-999,-1000],np.na) #对应替换 data.replace([-999,-1000],[np.na,0]) #对应替换也可以传入一个字典 data.replace({-999:np.na,-1000:0})
离散化
#定义分割点 bins=[20,40,60,80,100] #切割 cats = pd.cut(series,bins) #查看标签 cats.labels #查看水平(因子) cats.levels #区间计数 pd.value_count(cats) #自定义分区的标签 group_names=['youth','youngAdult','MiddleAge','Senior'] pd.cut(ages,bins,labels=group_names)
分位数分割
data=np.random.randn(1000) pd.qcut(data,4) #四分位数 #自定义分位数,包含端点 pd.qcut(data,[0,0.3,0.5,0.9,1])
异常值
#查看各个统计量 data.describe() #对某一列 col=data[3] col[np.abs(col)>3] #选出全部含有“超过3或-3的值的行 data[(np.abs(data)>3).any(1)] #异常值替换 data[np.abs(data)>3]=np.sign(data)*3
抽样
#随机抽取k行 df.take(np.random.permutation(len(df))[:k]) #随机抽取k行,但是k可能大于df的行数 #可以理解为过抽样了 df.take(np.random.randint(0,len(df),size=k))
数据摊平处理
#对摊平的数据列增加前缀 dummies = pd.get_dummies(df['key'],prefix='key') #将摊平产生的数据列拼接回去 df[['data1']].join(dummies)
字符串操作
# 拆分 strings.split(',') #根据正则表达式切分 re.split('\s+',strings) # 连接 'a'+'b'+'c'... 或者 '+'.join(series) # 判断是否存在 's' in strings` strings.find('s') # 计数 strings.count(',') # 替换 strings.replace('old','new') # 去除空白字符 s.strip()
正则表达式
正则表达式需要先编译匹配模式,然后才去匹配查找,这样能节省大量的CPU时间。re.complie:编译
findall:匹配所有
search:只返回第一个匹配项的起始和结束地址
match:值匹配字符串的首部
sub:匹配替换,如果找到就替换
#原始字符串 strings = 'sdf@153.com,dste@qq.com,sor@gmail.com' #编译匹配模式,IGNORECASE可以在使用的时候对大小写不敏感 pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}' regex = re.compile(pattern,flags=re.IGNORECASE) #匹配所有 regex.findall(strings) #使用search m = regex.search(strings) #获取匹配的地址 strings[m.start():m.end()] #匹配替换 regex.sub('new_string', strings)
根据模式再切分
将模式切分,也就是将匹配到的进一步切分,通过pattern中的括号实现.pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4})' regex = re.compile(pattern) regex.findall(strings) #如果使用match m=regex.match(string) m.groups() #效果是这样的 suzyu123@163.com --> [(suzyu123, 163, com)] #获取 list-tuple 其中的某一列 matches.get(i)
分组聚合,计算
group_by技术
# 根据多个索引分组,然后计算均值 means = df['data1'].groupby([df['index1'],df['index2']).mean() # 展开成透视表格式 means.unstack()
分组后价将片段做成一个字典
pieces = dict(list(df.groupby('index1'))) pieces['b']
groupby默认是对列(axis=0)分组,也可以在行(axis=1)上分组
语法糖,groupby的快捷函数
df.groupby('index1')['col_names'] df.groupby('index1')[['col_names']] #是下面代码的语法糖 df['col_names'].groupby(df['index1']) df.groupby(['index1','index2'])['col_names'].mean()
通过字典或series进行分组
people = DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim','Travis']) # 选择部分设为na people.ix[2:3,['b','c']]=np.na mapping = {'a': 'red', 'b': 'red', 'c': 'blue', 'd': 'blue', 'e': 'red', 'f' : 'orange'} people.groupby(mapping,axis=1).sum()
通过函数进行分组
#根据索引的长度进行分组 people.groupby(len).sum()
数据聚合
使用自定义函数
## 对所有的数据列使用自定义函数 df.groupby('index1').agg(myfunc) #使用系统函数 df.groupby('index1')['data1']describe()
根据列分组应用多个函数
#分组 grouped = df.groupby(['col1','col2']) #选择多列,对每一列应用多个函数 grouped['data1','data2'...].agg(['mean','std','myfunc'])
对不同列使用不同的函数
grouped = df.groupby(['col1','col2']) #传入一个字典,对不同的列使用不同的函数 #不同的列可以应用不同数量的函数 grouped.agg({'data1':['min','max','mean','std'], 'data2':'sum'})
分组计算后重命名列名
grouped = df.groupby(['col1','col2']) grouped.agg({'data1':[('min','max','mean','std'),('d_min','d_max','d_mean','d_std')], 'data2':'sum'})
返回的聚合数据不要索引
df.groupby(['sex','smoker'], as_index=False).mean()
分组计算结果添加前缀
#对计算后的列名添加前缀 df.groupby('index1').mean().add_prefix('mean_')
将分组计算后的值替换到原数据框
#将函数应用到各分组,再将分组计算的结果代换原数据框的值 #也可以使用自定义函数 df.groupby(['index1','index2'...]).transform(np.mean)
更一般化的apply函数
df.groupby(['col1','col2'...]).apply(myfunc) df.groupby(['col1','col2'...]).apply(['min','max','mean','std'])
禁用分组键
分组键会跟原始对象的索引共同构成结果对象中的层次化索引df.groupby('smoker', group_keys=False).apply(mean)
桶分析与分位数
对数据切分段,然后对每一分段应用函数frame = DataFrame({'col1':np.random.randn(1000), 'col2':np.random.randn(1000)}) #数据分段,创建分段用的因子 #返回每一元素是属于哪一分割区间 factor = pd.cut(frame.col1, 4) #分组计算,然后转成数据框形式 grouped = frame.col2.groupby(factor) grouped.apply(myfunc).unstack()
用分组的均值填充缺失值
#自定义函数 fill_mean= lambda x:x.fillna(x.mean()) #分组填充 df.groupby(group_key).apply(fill_mean)
分组后不同的数据替换不同的值
#定义字典 fill_value = {'east':0.5, 'west':-1} #定义函数 fill_func = lambda x:x.fillna(fill_value(x.name)) #分组填充 df.groupby(['index1','index2'...]).apply(fill_func)
相关文章推荐
- Python在Windows系统下安装环境的搭建
- python学习之11 加密解密hashlib
- 【Mastering Machine Learning with scikit-learn (python+spark版)】Chapter2 Linear Regression
- Win7下安装Python图像处理库PIL、pytesser、tesseract进行验证码识别
- python中requests的用法
- [LeetCode]题解(python):097-Interleaving String
- python模块系列之 - configparser
- Python扩展内置类型
- 一张图让你懂Python安装第三方库
- python解析xml配置文件
- [LeetCode]题解(python):096-Unique Binary Search Trees
- 《python核心编程》读书笔记--第18章 多线程编程
- Python 正则表达式(模式匹配)
- [LeetCode]题解(python):095-Unique Binary Search Trees II
- python学习之10 随机数random
- 平台后端开发(Python)面试记录
- Gihub项目分享 —— Python爬虫获取高清桌面壁纸
- numpy的random模块
- python __init__.py用途
- python-整理--pip whl命令