深入pandas

数据准备:

    加载

    组装:

        合并: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']

上一篇:python – 使用ctypes数组作为numpy数组时的PEP 3118警告


下一篇:selenium定位class含空格