数据准备:
加载
组装:
合并:pandas.mege()
拼接:pandas.concat()
组合:pandas.DataFrame.combine_first()
变形
删除
合并:
1.根据列合并
没有指定根据那一列合并
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','pencil','ball','pen'],
'color':['white','red','red','black']})
pd.merge(frame1,frame2)
不指定索引合并为空:
#*-* coding=utf-8 *-*
import numpy as np
import pandas as pd
frame1 = pd.DataFrame({'id': ['ball','pencil','pen','mug','ashtray'],
'color':['white','red','red','black','green'],
'brand':['OMG','ABC','ABC','PDD','PDD'] })
frame2 = pd.DataFrame({'id':['pencil','pencil','ball','pen'],
'brand':['OMG','PDD','ABC','PDD']})
pd.merge(frame1,frame2)
指定索引合并:
pd.merge(frame1,frame2,on='id')
pd.merge(frame1,frame2,on='brand')
假如两个DataFrame基准列的名称不一致,该怎样进行合并呢?
可以用 left_on和right_on选项指定第一个和第二个DataFrame的基准列。
frame1.columns = ['brand','sid']
pd.merge(frame1,frame2,left_on='id',right_on='sid')
merge()函数默认执行的是内连接操作;上述结果中的键是由交叉操作得到的。
其他选项有左连接、右连接和外连接。
外连接把所有的键整合到一起,其效果相当于左连接和右连接的效果之和。连接类型用how选项指定。
frame2.columns = ['brand','id']
pd.merge(frame1,frame2,on='id',how='outer')
pd.merge(frame1,frame2,on='id',how='left')
pd.merge(frame1,frame2,on='id',how='right')
要合并多个键,可以把键以列表的形式赋值给on
pd.merge(frame1,frame2,on=['id','brand'],how='outer')
2.根据索引合并
有时,合并操作不是用DataFrame的列而是用索引作为键。把left_index和right_index选项
的值置为True,将其激活,就可将其作为合并DataFrame的基准。
pd.merge(frame1, frame2, right_index=True, left_index=True)
DataFrame对象的join函数更适合于根据索引进行合并。
还可以用它合并多个索引相同或索引相同但列却不一致的DataFrame对象(列名称不能重合,否则报错)
frame2.columns = ['brand2','id2']
frame1.join(frame2)
2.拼接:
NumPy的 concatenate()函数就是用于数组的拼接操作。
pandas库以及它的 Series和DataFrame等数据结构实现了带编号的轴,它可以进一步扩展数组
拼接功能。 pandas的concat()函数实现了按轴拼接的功能。
ser1 = pd.Series(np.random.rand(4),index=[1,2,3,4])
ser2 = pd.Series(np.random.rand(4),index=[5,6,7,8])
pd.concat([ser1,ser2])
concat()函数默认按照axis=0这条轴拼接数据,返回Series对象。如果指定axis=1,返回结果
将是 Dataframe对象。
pd.concat([ser1,ser2],axis=1)
结果中无重合数据,因而刚执行的其实是外连接操作。把join选项置为'inner',可执行内
连接操作。
pd.concat([ser1,ser2],axis=1,join='inner')(有问题)
假如你想在用于拼接的轴上创建等级索引,就需要借助keys选项来完成。
pd.concat([ser1,ser2],keys=[1,2])
按照axis=1拼接 Series对象,所指定的键变为拼接后得到的 Data Frame对象各列的名称。
pd.concat([ser1,ser2],axis=1,keys=[1,2])
DataFrame对象的拼接方法与之相同。
组合:
combine first(函数可以用来组合 Series对象,同时对齐数据。
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)
ser2.combine_first(ser1)
如果你想进行部分合并,仅指定要合并的部分即可。
ser1[:3].combine_first(ser2[:3])
轴向旋转:
1.按等级索引旋转
轴向旋转有两个基础操作。
入栈( stacking):旋转数据结构,把列转换为行。
出栈( unstacking):把行转换为列。
对DataFrame对象应用stack()函数,会把列转换为行,从而得到一个Series对象
frame1 = pd.DataFrame(np.arange(9).reshape (3, 3),
index=['white', 'black','red',],
columns=['ball','pen', 'pencil'])
frame1.stack()
unstack()函数,可以重建之前的Dataframe对象,从而可以以数据透视表的形式来展示 Series对象中的等级索引结构。
ser = frame1.stack()
ser.unstack()
2.从“长”格式向“宽”格式旋转
pivot()函数,它以用作键的一列或多列作为参数。能够把长格式DataFrame转换为宽格式
删除:
frame1 = pd.DataFrame(np.arange(9).reshape (3, 3),
index=['white', 'black','red',],
columns=['ball','pen', 'pencil'])
删除一列
del frame1['ball']
删除多列:
frame1.drop('red')
3.数据转换
删除重复元素:
Data frame对象的duplicated()函数可用来检测重复的行,返回元素为布尔型的Series对象。
每个元素对应一行,如果该行与其他行重复(也就是说该行不是第一次出现),则元素为True;如果跟前面不重复,则元素就为 False。
dframe = pd.DataFrame({'color':['white','white','red','red','white'],
'value':[2,1,3,3,2]})
dframe.duplicated()
留下重复的行:
dframe[dframe.duplicated()]
删掉重复的行:
drop_duplicates()函数实现了删除功能,该函数返回的是删除重复行后的DataFrame对象。
dframe.drop_duplicates()
映射:
映射关系无非就是创建一个映射关系列表,把元素跟一个特定的标签或字符串绑定起来。最好的就是字典。
1.用映射替换元素
把映射关系字典的值替换:
frame = pd.DataFrame( {'id': ['ball','pencil','pen','mug','ashtray'],
'color':['white','rosso','verde','black','yellow'],
'price':[12.33,11.44,33.21,13.23,33.62]})
new = {
'rosso':'red',
'verde':'green'
}
frame.replace(new)
把NaN替换:
ser = pd.Series([1,3,np.nan,4,6,np.nan,3])
ser.replace(np.nan,0)
2.用映射添加元素
frame = pd.DataFrame({'id':['pencil','pencil','ball','pen'],
'brand':['OMG','PDD','ABC','PDD']})
price = {
'pencil':'12.33',
'pencil':'11.44',
'ball':'33.21',
'pen':'13.23',}
frame['price'] = frame['id'].map(price)
3.重命名轴索引
pandas的rename()函数,以表示映射关系的字典对象作为参数,替换轴的索引标签。
reindex = {
0:'first',
1:'second',
2:'third',
3:'fourth'}
frame.rename(reindex)
修改列:
recolumns = {id = 'object'}
frame.rename(index=reindex,columns=recolumns)
对于只有单个元素要替换的最简单情况,可以对传入的参数做进一步限定,而无需把多个变量都写出来,也避免产生多次赋值操作.
frame.rename(index={1:'first'},columns={'id':'object'})
rename()函数返回一个经过改动的新 Data frame对象,但原DataFrame对象仍保持不变。如果要改变调用函数的对象本身,可使用 inplace选项,并将其值置为True。
frame.rename(,columns={'id':'object'},inplace=True)
4.离散化和面元划分:
有时,要处理的大量数据为连续型的。为了便于分析它们,需要把数据打散为几个类别,例如把(仪器)读数的取值范围划分为一个个小区间,统计每个区间的元素数量或其他统计量。
另外一种情况是,对总体做出精确的测量,得到了大量个体。这种情况下,为了便于数据分析,也需要把元素分成几个类别,然后分别分析每个类别的个体数量及其他统计量。
已知实验数据的范围为0-100,因而我们可以把数据范围均分,比如分为四部分,也就是四个面元(bin)。第一个面元包含0-25的值,第二个为26~50,第三个为51~75,最后一个为76~100。
result = [22,45,78,46,87,8,44,45,16,76,18,34,19]
用pandas划分面元之前,首先要定义一个数组,存储用于面元划分的各数值。
bins=[0,25,50,75,100]
然后,对results数组应用cut()函数,同时传入bins变量作为参数。
cat= pd.cut(results, bins)
cut()函数返回的对象为Categorical1(类别型)类型,可以将其看作一个字符串数组,其元素为面元的名称。该对象内部的levels数组为不同内部类别的名称,labels数组的元素数量跟results数组(也就是说,划分成各面元的数组)相同,labels数组的各数字表示results元素所属的面元。
cat.levels(没有)
cat.labels
若想指定每个面元的出现次数,即每个类别有多少个元素,可使用value_counts()函数
pd.value_counts(cat)
可以用字符串数组指定面元的名称,把它赋给cut()函数的1abels选项,然后用该函数创建categorical对象。
bin_names =['unlikely', 'less likely, 'likely','highly likely']
cat= pd.cut(results, bins,labels=bin_names)
若不指定面元的各界限,而只传入一个整数作为参数,cut()函数就会按照指定的数字,把数组元素的取值范围划分为相应的几部分。
cat= pd.cut(results, 5)
qcut():这个函数直接把样本分成五个面元。用cut()函数划分得到的面元,每个面元的个体数量不同,具体跟数据样例的分布相关。
而qcut()函数能够保证每个面元的个体数相同,但每个面元的区间大小不等。
qcat = pd.qcut(results, 5)
异常值检测和过滤
randfrmme = pd.DataFrame(np.random.rand(1000,3))
describe()函数查看每一列的描述性统计量
randfrmme.describe()
std()函数就可以求得 Data Frame对象每一列的标准差。
5.排序:
numpy. random. permutation()函数排序:
用permutation()函数创建一个包含04(顺序随机)这五个整数的数组。将按照这个数
组元素的顺序为Dataframe对象的行排序。
对 Data frame对象的所有行应用take()函数,把新的次序传给它。
nframe = pd.DataFrame(np.arange(25).reshape(5,5))
new_order = np.random.permutation(5)
nframe.take(new_order)
还可以只对DataFrame对象的一部分进行排序操作。它将生成一个数组,只包含特定索引范围的数据
new_order = [4,3,2]
nframe.take(new_order)
随机取样:
sample = np.random.randint(0,len(nframe),size=3)
nframe.take(sample)
6.字符串处理:
1.内置的字符串处理方法:
split()
strip()
join()
index()
find()
count()
replace()
2.正则
7.数据聚合:
1.GroupBy:
Group By过程及其工作原理。
Group By通常指的是它的内部机制SPLIT-APPLY-COMBⅠNE(分组-用函数处理合并结果)过程。它的操作模式由三个阶段组成,每个阶段可以用一种操作来准确地表示。
1.分组:将数据集分成多个组
2.用函数处理:用函数处理每一组
3.合并:把不同组得到的结果合并起来
分组阶段,根据给定标准,把Series或 Data Frame等数据结构中的数据分为几个不同的组,分组标准常与索引或某一列具体的元素相关。用SQL的行话来说,作为分组标准的这一列被称作键。进一步来说,如果你处理的是Dataframe等二维对象,分组标准可以既应用于行(axis=0),也应用于列(axis=1)。
第二个阶段也称作“用函数处理”,使用函数处理或者执行由函数定义的计算,为每组数据生成单一的值。
最后一步为合并,把来自每一组的结果汇集到一起,合并成一个新对象。
2.实例:
groupby()函数
frame = pd.DataFrame({'color':['white','red', 'green','red','green'],
'object':['pen','pencil','pencil','pen','pen'],
'price1':[5.56,4.20,1.30,0.56,2.75],
'price2':[4.75,4.12,1.60,0.75,3.15]})
使用 color列的组标签,计算price列的均值,方法有多种。例如,可以先获取到price1列,然后再调用groupby()函数,用参数指定 color这一列。
group= frame['price1'].groupby( frame['color'])
刚执行的操作其实没有进行任何计算,它只是把计算需要的所有信息放到了一起。你刚进行的操作其实就是分组操作,把含有相同颜色的行分到同一个组里。
GroupBy对象的 groups属性,我们来详细看一下 DataFrame各行的分组情况。
group.groups
group.mean()
group.sum()
3.等级分组
还可以用多列,也就是使用多个键,按照等级关系分组。
ggroup= frame['price1'].groupby([frame['color'],frame['object']])
ggroup.groups
ggroup.sum()
可以按照多列数据或整个Dataframe把数据分为几组。如果不想重复多次使用GroupBy对象,最方便的方法是一次就把所有的分组依据和计算方法都指定好,而无需定义任何中间变量。
group= frame[['price1','price2']].groupby( frame['color']).mean()
frame.groupby(frame['color']).mean()
8.组迭代
GroupBy对象还支持迭代操作,它可以生成一系列由各组名称及其数据部分组成的元组。
for name,group in frame.groupby('color'):
print(name)
print(group)
1.链式转换
用函数进行计算或执行其他操作时,不管各组是怎么得到的以及选取标准是什么,最终结果不是 Series(如果只选择一列数据)就是Dataframe数据结构,它们保留了索引系统和列名称。
frame['price1'].groupby( frame['color']).mean()
frame.groupby(frame['color'])['price1'].mean()
(frame.groupby(frame['color']).mean()).['price1']
此外,执行聚合操作后,某些列的名称可能存在表意不明确的现象。这时,在列名称前加上描述操作类型的前缀很有用。注意,添加前缀而不是完全替换名称,这样可以便于跟踪聚合数据的源数据。如果你采用的是链式转换过程(DataFrame之间存在生成关系),而又需要保留和源数据的对应关系,就可以使用这种方法。
frame.groupby(frame['color']).mean().add_prefix('mean_')
2.分组函数
quantile()函数计算分位数。
group = frame.groupby('color')
group['price'].quantile(0.6)
还可以自定义聚合函数。定义好函数后,将其作为参数传给agg()函数
def range(series):
return series.max() - serise.min()
group['price1'].agg(range)
可以对整个DataFrame对象应用agg()函数。
group.agg(range)
还可以同时使用多个聚合函数,把存放有表示聚合操作类型的数组传给agg()函数
group['price1']agg(['mean', 'std', 'range'])
9.高级数据聚合
transform()和apply()函数,它们可以用来执行多种甚至是非常复杂的组操作。
frame= pd.DataFrame({'color': ['white','red','green','red','green']
'price1':[5.56,4.20,1.30,0.56,2.75],
'price2':[4.75,4.12,1.60,0.75,3.15]})
sums = frame.groupby('color').sum().add_prefix('tot_')
merge(frame,sums,left_on='color',right_index=True)
可以用merge()函数把聚合操作的计算结果添加到Dataframe对象的每一行。实际上,你也可以用transform()方法实现这种操作。该函数执行聚合操作的方式跟前面讲过的相同,但它还可
以根据 DataFrame对象每一行的关键字显示聚合结果。
sums = frame.groupby('color').transfrom(np.sum).add_prefix('tot_')
appy()函数则适用于执行更为一般的GroupBy操作。这个方法完全实现了SPLIT-APPLY-COMBINE机制。它把对象分为几部分后,再用函数处理每一部分,各步骤之间用链式方法连接在一起
frame= DataFrame({'color': ['white', 'black', 'white', 'white', 'black', 'black',]
'status': ['up','up','down','down','down','up'],
'value1':[12.33,14,55,22,34,27.84,23.40,18,33],
'value2':[11.23,31,80,29.99,31,18,18.25,22,44]})
frame.groupby(['color','status']).apply(lambda x: x.max())
frame.rename(index=reindex, columns=recolumn)
temp=date_range(1/1/2015, periods=10, freq= 'H')
timeseries= Series(np.random.rand(10),index=temp)
imetable= DataFrame({'date': temp,'value1':np.random.rand(10),
'value2': np.random.rand(10)})
timetable['cat']=['up','down','left','left','up','up','down','right','right','up']