深入pandas 数据处理
三个阶段
- 数据准备
- 数据转化
- 数据聚合
- 加载
- 组装
- 合并 - pandas.merge()
- 拼接 - pandas.concat()
- 组合 - pandas.DataFrame.combine_first()
- 变形
- 删除
合并
example1:
import numpy as np
import pandas as pd
frame1 = pd.DataFrame({'id':['ball','pencil','pen','mug','ashtray'],'price':[12.33,11.44,33.21,13.23,33.62]})
frame2 = pd.DataFrame({'id':['pencil','ball','pencil','pen'],'color':['white','red','red','black']})
pd.merge(frame1,frame2)
有必要定义合并操作的标准 用 on 来指定
example2:
frame2.columns=['brand2','id2']
pd.merge(frame1,frame2,on='brand') # 需要重新明明
pd.merge(frame1,frame2,right_on='brand', left_on='sid')
拼接
concatenation
numpy 的 concatenate()函数就是做这种拼接操作
array1=np.arange(9).reshape((3,3))
array2=np.arange(9).reshape((3,3))+6
np=concatenate([array1,array2],axis=1)# axis=1 从行拼接 axis=0 从列拼接
pandas的concat()函数可以做拼接操作
ser1=pd.concat([ser1,ser2])
# axis=1 从行拼接 axis=0 从列拼接
# join='inner' or 'outer'
组合
Series对象: combine_first()
组合的同时还可以对齐数据
ser1=pd.Series(np.random.rand(5),index=[1,2,3,4,5])
ser2=pd.Series(np.random.rand(4),index=[2,4,5,6])
ser1.combine_first(ser2)
轴向旋转
意思是 需要按照行重新调整列或者反过来
两个操作:
- stacking 入栈, 把列转化为行
- unstacking 出站, 把行转化为列
frame1=pd.DataFrame(np.arange(9).reshape(3,3),index=['w','b','r'], columns=['ball','pen','pencil'])
frame1.stack() # 得到一个Series对象
ser.unstack() # 得到一个DataFrame对象
# 长格式向宽格式转化: DateFrame.pivot
wideframe=longframe.pivot('color','item')
- 删除一列
del frame['ball']
- 删除多余的行
frame.drop('white')
删除重复数据
DataFrame 中duplicated()函数可以用来检测重复的行,返回bool型Series对象
dframe.duplicated()
# 得到过滤结果
dframe[dframe.duplicated()]
# 讲重复的行删除
dframe.drop_duplicates<>
映射
dict 映射关系比较好
replace() 替换元素
map() 新建一列
rename() 替换索引
### 替换
newcolor={'rosso':'red','verde':'green'}
frame.replace(newcolors)
ser.replace(np.nan, 0)
### 添加元素
price={'ball':5.56,'mug':4.3}
frame['price']=frame['item'].map(price)
### 重命名轴索引
reindex={o:'first',2:'second'}
frame.replace(reindex)
frame.replace(index={1:'first'}, columns={'item':'object'})
# inplace 参数: 是否改变调用函数对象本身
离散化
result=[12,34,67,55,28,90.99,12,3,56,74,44,87,23,49,89,87]
bins=[0,25,50,75,100]
# 对result用cut函数
cat=pd.cut(result,bins)
cat >>> type(cat)
<class 'pandas.core.categorical.Categorical'>
# 返回的是类别对象
cat.levels
cat.labels
# 类别中计数
pd.value_counts(cat)
# cut 函数中的labels标签 labels=['a','b','c']
异常值的检测和过滤
randframe=pd.DataFrame(np.random.randn(1000,3))
descibe()函数查看每一列的描述性统计量
假设讲比标准差大三倍的元素是为异常值,用std()函数可以求出每一列的标准差
randframe.std()
对DataFrame对象进行过滤
randframe[(np.abs(randframe)>(3*randframe.std())).any(1)]
排序
nframe=pd.DataFrame(np.arange(25).reshape(5,5))
# permutation(5)创建一个随机顺序整数
new_order=np.random.permutation(5) # 0-4
nframe.take(new_order)
随机取样
np.random.randint()函数
sample=np.random.randint(0,len(nframe),size=3)
字符串处理
内置字符串处理方法
split() 函数 切割
test='12312,bob'
test.split(',')
# ['12312', 'bob']
strip()函数 去空白
tokens=[s.strip() for s in test.split(',')]
join() 拼接
>>> strings=['1','2','3','45','5']
','.join(strings)
in index() find() 查找操作
test.index('bottom')
test.find('bottom')
'bottom' in test
count() 出现次数
test.count('bottom')
replace()
test.replace('A','a')
正则表达式
import re
几个类别:
- 模式匹配
- 替换
- 切分
re.split()
text="This is an \t odd \n text!"
re.split('\s+',text)
# 内部过程
regex=re.compile('\s+')
regex.split(text)
re.findall()
# 以A开头不区分大小写
text='A! This is my address: 16 Boltom Avenue, Boston'
re.findall('[A,a]\w+',text)
GroupBy
SPLIT-APPLY-COMBINE 三个阶段
- 分组
- 用函数处理
# 实际上只使用了GroupBy函数
frame=pd.DataFrame({'color':['white','red','green','red','green'],'obj':['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.3,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})
>>> frame
color obj price1 price2
0 white pen 5.56 4.75
1 red pencil 4.20 4.12
2 green pencil 1.30 1.60
3 red ashtray 0.56 0.75
4 green pen 2.75 3.15
# 想要根据color组,计算price1的均值
group=frame['price1'].groupby(frame['color'])
# 得到一个group对象
group.groups # 查看分组情况
group.mean() # 查看均值
group.sum() # 查看分组总和
等级分组
ggroup=frame['price1'].groupby([frame['color'],frame['obj']])
frame[['price1','price2']].groupby(frame['color']).mean()
组迭代
for name, group in frame.groupby('color'):
print(name)
print(group)
分组函数
group=frame.groupby('color')
group['price1'].quantile(0.6) # 直接计算分位数
# 自定义聚合函数
def range(series):
return series.max()-series.min()
group['price1'].agg(range)
group.agg(range)
代码改变世界