44.Python编程:Pandas详解

作者: TensorFlow开发者 | 来源:发表于2018-10-07 02:05 被阅读31次

    什么是pandas

    pandaspython的一个数据分析包,是基于NumPy的一种工具,该工具是为了解决数据分析任务而创建的。pandas纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

    pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 Pandas的名称来自于面板数据(panel data)python数据分析(data analysis)

    panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。

    简言之,pandas是基于NumPy的,两者是数据分析强大的工具。

    pandas安装

    pandas安装指令:

    pip install pandas
    

    pandas中数据结构Series和DataFrame

    pandas中主要有两种数据结构,分别是:Series和DataFrame

    Series

    Series:一种类似于一维数组的对象,是由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。仅由一组数据也可产生简单的Series对象。

    创建Series对象,用到pandas中的Series()

    • 通过一维数组创建Series对象

    创建数据是一维数组,也可以是字典。前面一文NumPy详解中,已详细学习了NumPy一维数组的各种创建,此处不再赘述。我们只需把创建好的一维数组数据传递过来即可。示例如下:

    import pandas as pd
    import numpy as np
    
    # Series
    
    # 通过随机数创建numpy数组
    arr = np.random.randn(6)
    s1 = pd.Series(arr)
    print(s1)
    print("-" * 20)
    
    # 通过arange()创建numpy数组
    arr2 = np.arange(6)
    s2 = pd.Series(arr2)
    print(s2)
    print("-" * 20)
    
    # 通过ones创建numpy的全1数组
    arr3 = np.ones(6)
    s3 = pd.Series(arr3)
    print(s3)
    print("-" * 20)
    
    # 通过zeros创建numpy的全零数组
    arr4 = np.zeros(6)
    s4 = pd.Series(arr4)
    print(s4)
    

    运行结果:

    0   -1.205245
    1   -0.671404
    2   -0.056164
    3   -0.090229
    4    1.004950
    5   -1.139511
    dtype: float64
    --------------------
    0    0
    1    1
    2    2
    3    3
    4    4
    5    5
    dtype: int32
    --------------------
    0    1.0
    1    1.0
    2    1.0
    3    1.0
    4    1.0
    5    1.0
    dtype: float64
    --------------------
    0    0.0
    1    0.0
    2    0.0
    3    0.0
    4    0.0
    5    0.0
    dtype: float64
    

    说明:
    上面例子中,我们在创建Series对象,只提供了数据源,并没有提供索引。此时索引默认是从0开始的数字,依次排序。当然,我们也可以在创建的时候,指定索引:

    import pandas as pd
    import numpy as np
    
    # Series
    
    # 创建的时候,指定索引
    arr = np.random.randn(6)
    s5 = pd.Series(arr, index=["一月", "二月", "三月", "四月", "五月", "六月"])
    print(s5)
    

    运行结果:

    一月    0.088578
    二月    0.347118
    三月   -1.080161
    四月   -0.937341
    五月    1.216052
    六月    0.646635
    dtype: float64
    
    • 通过字典创建Series对象

    上面例子中,我们在创建Series对象,数据源是一维数组,当然我们也可以传入字典来创建Series对象。字典的key就是要生成Series的索引了。

    import pandas as pd
    
    # Series
    
    dict_data = {"一月": 11, "二月": 13, "三月": 10, "四月": 14, "五月": 8, "六月": 10}
    
    # 通过字典创建Series对象
    s3 = pd.Series(dict_data)
    print(s3)
    

    运行结果:

    一月    11
    二月    13
    三月    10
    四月    14
    五月     8
    六月    10
    dtype: int64
    
    • 取值

    我们从Series数据结构中取值,可以利用自定义的索引标签,也可以利用默认的位置索引。上面例子中可以这样取值:

    # 上接
    
    # 通过标签取值
    print(s3["一月"])
    
    # 通过默认的索引序列取值
    print(s3[0])
    

    运行结果:

    11
    11
    

    Series一维数据结构很简单,我们重点去学习二维数据结构DataFrame

    注意:Series中的索引值是可以重复的。

    DataFrame

    DataFrame:一个二维表格型的数据结构,包含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型等),DataFrame即有行索引也有列索引,可以被看做是由Series组成的字典。

    DataFrame对象的创建,要用到pandas 中的DataFrame()。需要传入的参数,数据源可以是二维数组,也可以是字典。除此之外,创建的同时也可以指定行索引,列索引。如果不指定索引,将使用默认的索引,从0开始的依次递增的序列号。

    import pandas as pd
    import numpy as np
    
    # DataFrame
    
    # 利用numpy创建二维数据
    arr = np.random.randn(20).reshape((4, 5))
    
    # 利用pandas创建DataFrame对象
    df = pd.DataFrame(arr)
    
    print(df)
    

    运行结果:

              0         1         2         3         4
    0 -1.719292  0.437608  0.512311 -0.658363 -0.114165
    1 -0.730688  1.887302  0.495906  0.109294  0.484358
    2  2.716056 -2.124497 -0.406951  1.396759  1.621959
    3  1.923468 -0.129051  0.218899  2.427141  0.781985
    

    我们可以在创建的同时,可以指定行索引、列索引。示例如下:

    import pandas as pd
    import numpy as np
    
    # DataFrame
    
    # 利用numpy创建二维数据
    arr = np.random.randn(20).reshape((4, 5))
    
    # 行索引
    index = ["Q1", "Q2", "Q3", "Q4"]
    
    # 列索引
    columns = ["A", "B", "C", "D", "E"]
    
    # 利用pandas创建DataFrame对象
    df = pd.DataFrame(arr, index=index, columns=columns)
    
    print(df)
    

    运行结果:

               A         B         C         D         E
    Q1  0.064423  1.633352 -1.705736  1.305984  0.001379
    Q2  0.445133  0.452308  1.659449 -0.800272  0.986402
    Q3 -0.024076  1.090810 -0.627166 -0.312072  0.242472
    Q4 -2.754748 -0.757759  0.689985 -0.001170 -0.136409
    
    常见属性

    我们可以获取行索引df.index、列索引df.columns、数据值df.values、数据描述df.describe(),示例如下:

    import pandas as pd
    import numpy as np
    
    # DataFrame
    
    # 利用numpy创建二维数据
    arr = np.random.randn(20).reshape((4, 5))
    
    # 行索引
    index = ["Q1", "Q2", "Q3", "Q4"]
    
    # 列索引
    columns = ["A", "B", "C", "D", "E"]
    
    # 利用pandas创建DataFrame对象
    df = pd.DataFrame(arr, index=index, columns=columns)
    
    print(df)
    print("-" * 50)
    
    # 行索引
    print(df.index)
    
    # 列索引
    print(df.columns)
    print("-" * 50)
    
    # 数据值
    print(df.values)
    
    print("-" * 50)
    
    # 数据描述信息
    print(df.describe())
    

    运行结果:

               A         B         C         D         E
    Q1  0.752826 -1.355122  0.035948  0.839446  0.635179
    Q2 -0.496016 -0.322719  0.885232  0.247262 -0.906780
    Q3  0.845926  1.073606  0.233991 -0.236160  0.147905
    Q4  0.030459  1.391417 -0.346198  1.991587 -0.303235
    --------------------------------------------------
    Index(['Q1', 'Q2', 'Q3', 'Q4'], dtype='object')
    Index(['A', 'B', 'C', 'D', 'E'], dtype='object')
    --------------------------------------------------
    [[ 0.75282594 -1.35512209  0.03594756  0.83944646  0.63517926]
     [-0.49601568 -0.32271876  0.8852321   0.24726162 -0.90678047]
     [ 0.84592563  1.07360619  0.23399063 -0.23615957  0.14790464]
     [ 0.03045917  1.39141744 -0.34619834  1.99158653 -0.30323524]]
    --------------------------------------------------
                  A         B         C         D         E
    count  4.000000  4.000000  4.000000  4.000000  4.000000
    mean   0.283299  0.196796  0.202243  0.710534 -0.106733
    std    0.634629  1.274658  0.515081  0.960653  0.656750
    min   -0.496016 -1.355122 -0.346198 -0.236160 -0.906780
    25%   -0.101160 -0.580820 -0.059589  0.126406 -0.454122
    50%    0.391643  0.375444  0.134969  0.543354 -0.077665
    75%    0.776101  1.153059  0.396801  1.127481  0.269723
    max    0.845926  1.391417  0.885232  1.991587  0.635179
    

    说明:通过df.describe()获取的数据描述信息,包含了每一列数据的总个数count、每一列平均值mean、每一列标准差std、每一列最小值min、每一列最大值max等信息。

    排序sort

    排序可以根据索引排序df.sort_index(axis=0, ascending=False),其中,axis=0或1等,0表示竖直方向上对行排序,1表示水平方向上对列排序,ascending=True或False,表示是按升序还按照降序排序。

    import pandas as pd
    import numpy as np
    
    # 利用numpy创建二维数据
    arr = np.random.randn(20).reshape((4, 5))
    
    # 行索引
    index = ["Q1", "Q2", "Q3", "Q4"]
    
    # 列索引
    columns = ["A", "B", "C", "D", "E"]
    
    # 利用pandas创建DataFrame对象
    df = pd.DataFrame(arr, index=index, columns=columns)
    
    print(df)
    
    # 按行索引降序排序
    print(df.sort_index(axis=0, ascending=False))
    

    运行结果:

               A         B         C         D         E
    Q1  1.204422 -0.670984 -0.068458 -1.694837 -0.091393
    Q2 -0.359985 -0.043025  2.100953  0.093833  0.523428
    Q3  0.234466  1.977082  1.352345  1.378801  0.399397
    Q4 -1.641561  0.036706  1.189736 -0.076161 -0.500466
               A         B         C         D         E
    Q4 -1.641561  0.036706  1.189736 -0.076161 -0.500466
    Q3  0.234466  1.977082  1.352345  1.378801  0.399397
    Q2 -0.359985 -0.043025  2.100953  0.093833  0.523428
    Q1  1.204422 -0.670984 -0.068458 -1.694837 -0.091393
    

    说明:按照行或列索引排序,索引是排好序的,但值不一定是排好序的。

    也可以根据值排序df.sort_values(axis=0, by="A", ascending=False),根据值排序时,要传入根据哪一行或哪一列的数据排序。

    特别注意的是,如果axis=0,表示既然竖直方向上对行排序,则此时by="标签名"标签名只能传入列标签名,表示依据此列元素的值排序。同理,如果axis=1,表示既然水平方向上对行排序,则此时by="标签名"标签名只能传入行标签名,表示依据此行元素的值进行排序。

    import pandas as pd
    import numpy as np
    
    # 利用numpy创建二维数据
    arr = np.random.randn(20).reshape((4, 5))
    
    # 行索引
    index = ["Q1", "Q2", "Q3", "Q4"]
    
    # 列索引
    columns = ["A", "B", "C", "D", "E"]
    
    # 利用pandas创建DataFrame对象
    df = pd.DataFrame(arr, index=index, columns=columns)
    
    print(df)
    
    # 对数据值,根据A列数据的值,降序排序
    print(df.sort_values(axis=0, by="A", ascending=False))
    
    print("-" * 50)
    
    # 对数据值,根据Q1行数据的值,升序排序
    print(df.sort_values(axis=1, by="Q1", ascending=True))
    

    运行结果:

               A         B         C         D         E
    Q1 -0.732549 -1.738364  0.651045 -0.639112 -2.327446
    Q2 -2.366076 -0.090833 -0.070340 -0.373408 -0.195486
    Q3 -0.270237 -0.087023 -0.185530  0.600220  1.122631
    Q4  0.486386  1.656176  0.667432  0.718930 -1.326645
    
               A         B         C         D         E
    Q4  0.486386  1.656176  0.667432  0.718930 -1.326645
    Q3 -0.270237 -0.087023 -0.185530  0.600220  1.122631
    Q1 -0.732549 -1.738364  0.651045 -0.639112 -2.327446
    Q2 -2.366076 -0.090833 -0.070340 -0.373408 -0.195486
    --------------------------------------------------
               E         B         A         D         C
    Q1 -2.327446 -1.738364 -0.732549 -0.639112  0.651045
    Q2 -0.195486 -0.090833 -2.366076 -0.373408 -0.070340
    Q3  1.122631 -0.087023 -0.270237  0.600220 -0.185530
    Q4 -1.326645  1.656176  0.486386  0.718930  0.667432
    

    选择数据

    DataFrame选择数据可以通过行、列标签名df.loc[标签名],也可以通过索引df.iloc[索引值或切片],也可混合上面两种取值df.ix[标签名, 索引值或切片]

    • 通过行、列标签名选择数据

    通过行、列标签名选择数据,用到df.loc[标签名],示例如下:

    数据源:

               A         B         C         D         E         F
    R0  1.011527 -1.682691 -0.638201 -0.209897  0.349887 -0.238343
    R1 -2.226714 -0.903630 -0.538594  2.001834  2.235736 -0.759220
    R2 -0.351387 -0.003949  0.686346 -0.103567  0.800941 -1.399295
    R3 -0.001803 -1.968112 -0.147488  1.152809  0.598925  0.549745
    R4  0.604023  0.417916  0.544499 -0.895700 -0.323974 -2.276000
    

    根据行标签取一整行:

    # 根据行标签取一整行
    df.loc["R0"]
    

    得到数据:

    A    1.011527
    B   -1.682691
    C   -0.638201
    D   -0.209897
    E    0.349887
    F   -0.238343
    Name: R0, dtype: float64
    

    根据列标签取一整列:

    # 根据列标签取一整列
    print(df.loc[:, "A"])
    

    得到数据:

    R0    1.011527
    R1   -2.226714
    R2   -0.351387
    R3   -0.001803
    R4    0.604023
    Name: A, dtype: float64
    

    根据行标签取R0、R1、R2,3整行:

    # 根据行标签取R0、R1、R2,3整行
    df.loc["R0":"R2"]
    

    得到数据:

               A         B         C         D         E         F
    R0  1.011527 -1.682691 -0.638201 -0.209897  0.349887 -0.238343
    R1 -2.226714 -0.903630 -0.538594  2.001834  2.235736 -0.759220
    R2 -0.351387 -0.003949  0.686346 -0.103567  0.800941 -1.399295
    
    

    根据行标签取R0行中在A、B、C 三列中的元素:

    # 根据行标签取R0行中在A、B、C 三列中的元素
    df.loc["R0", "A":"C"]
    

    得到数据:

    A    1.011527
    B   -1.682691
    C   -0.638201
    Name: R0, dtype: float64
    

    • 通过索引选择数据

    通过索引选择数据,用到df.iloc[索引值或切片],示例如下:
    用到的数据源:

               A         B         C         D         E         F
    R0  1.476388 -0.433099 -1.267180  0.494799  0.221961  2.321015
    R1 -0.942005  0.120891 -2.199903 -1.065044  0.371607 -1.600735
    R2 -0.881376  0.439391 -2.043897  0.153790  0.084514  1.015457
    R3  0.133820  0.405521 -0.894834 -0.477888 -0.272330  0.763863
    R4 -0.664487  1.887760  1.341702 -0.161265  1.048645  1.391557
    

    根据行索引取一整行:

    # 根据行索引取一整行
    df.iloc[0]
    

    得到数据:

    A    1.476388
    B   -0.433099
    C   -1.267180
    D    0.494799
    E    0.221961
    F    2.321015
    Name: R0, dtype: float64
    

    根据列索引取一整列:

    # 根据列索引取一整列
    df.iloc[:, 0]
    

    得到数据:

    R0    1.476388
    R1   -0.942005
    R2   -0.881376
    R3    0.133820
    R4   -0.664487
    Name: A, dtype: float64
    

    根据行索引取R0、R1、R2, 3整行:

    # 根据行索引取R0、R1、R2, 3整行
    df.iloc[0:3]
    

    得到数据:

               A         B         C         D         E         F
    R0  1.476388 -0.433099 -1.267180  0.494799  0.221961  2.321015
    R1 -0.942005  0.120891 -2.199903 -1.065044  0.371607 -1.600735
    R2 -0.881376  0.439391 -2.043897  0.153790  0.084514  1.015457
    
    

    根据行标签取R0、R1行中在A、B、C 三列中的元素:

    # 根据行标签取R0、R1行中在A、B、C 三列中的元素
    df.iloc[0:2, 0:3]
    

    得到数据:

               A         B         C
    R0  1.476388 -0.433099 -1.267180
    R1 -0.942005  0.120891 -2.199903
    

    • 混合上面两种方式取值

    混合上面两种方式取值df.ix[ ],形如:df.ix["R0":"R2", 1:3]
    用到的数据源:

               A         B         C         D         E         F
    R0  1.966476  0.768749  1.741041 -0.852826  0.803514 -1.820019
    R1 -0.077837 -0.187937 -0.043093  0.033061  0.874705  0.788629
    R2 -1.069619  1.824115 -1.213599 -1.193291 -0.841343 -0.511017
    R3 -1.285230  0.210782 -0.081224  0.929470  0.134794 -0.184362
    R4  0.768942 -1.698733  0.510024  0.036163 -0.250046 -2.846145
    

    混合取值:

    # 混合取值
    print(df.ix["R0":"R2", 1:3])
    

    得到的结果:

               B         C
    R0  0.768749  1.741041
    R1 -0.187937 -0.043093
    R2  1.824115 -1.213599
    

    空数据处理

    我们已经知道,pandas是基于numpy的,numpy对某个位置处的数据不存在时用NaN来进行标记。

    • df.isnull()是否空数据

    DataFrame对象可以用isnull()判断某个位置处的元素是否为空。不为空,该位置显示为False,为空则显示为True
    用到的数据源:

               A         B         C         D         E         F
    R0  0.528350       NaN       NaN -0.303180 -1.612900       NaN
    R1 -1.879040  0.735716 -1.109263 -0.718037  0.631095  0.174179
    R2 -0.655658       NaN       NaN  0.723953  0.777969       NaN
    R3 -0.020232       NaN       NaN -1.902687 -0.368842       NaN
    R4  0.858285 -1.073122  0.158649 -0.123761  1.075735  1.131269
    

    判断某个位置处的元素是否为空:

    df.isnull()
    

    运行结果:

           A      B      C      D      E      F
    R0  False   True   True  False  False   True
    R1  False  False  False  False  False  False
    R2  False   True   True  False  False   True
    R3  False   True   True  False  False   True
    R4  False  False  False  False  False  False
    
    • 丢掉空元素

    DataFrame对象可以用df.dropna(axis=0, how="any")对含有空元素的行或列进行丢弃。其中入参说明如下:

    axis=0或1axis=0表示对行舍弃;axis=1表示对列舍弃;
    how="any"或"all"how="any"表示某行或列只要包含有Nan就舍弃该行或列;how="all"表示只有当该行或列所有元素都是Nan,才舍弃该行或列,具体是舍弃行还是舍弃列,依据axis=的值为0还是1

    使用到的数据源:

               A         B         C         D         E         F
    R0 -0.971986       NaN       NaN -0.068481 -0.514055       NaN
    R1       NaN       NaN       NaN       NaN       NaN       NaN
    R2 -0.266219       NaN       NaN  0.963201  0.538803       NaN
    R3  1.137753       NaN       NaN -0.519390 -2.327215       NaN
    R4  1.550748 -0.532099  0.935743 -0.432936 -0.379045 -1.170906
    

    axis=0, how="any"舍弃含有Nan的行:

    # axis=0, how="any":舍弃含有Nan的行
    print(df.dropna(axis=0, how="any"))
    

    运行结果:

               A         B         C         D         E         F
    R4  1.550748 -0.532099  0.935743 -0.432936 -0.379045 -1.170906
    

    说明:由于df.dropna(axis=0, how="any")舍弃含有Nan的行,且数据源中,含有NaN的行是R0、R1、R2、R3,所以将R0、R1、R2、R3行舍弃,仅剩R4行。


    axis=0, how="all"舍弃某行元素都为Nan的行:

    # axis=0, how="all" 舍弃某行元素都为Nan的行
    print(df.dropna(axis=0, how="all"))
    

    运行结果:

               A         B         C         D         E         F
    R0 -0.971986       NaN       NaN -0.068481 -0.514055       NaN
    R2 -0.266219       NaN       NaN  0.963201  0.538803       NaN
    R3  1.137753       NaN       NaN -0.519390 -2.327215       NaN
    R4  1.550748 -0.532099  0.935743 -0.432936 -0.379045 -1.170906
    

    说明:由于df.dropna(axis=0, how="all")舍弃某行元素都为Nan的行,且数据源中,所有元素都为NaN的行是R1,所以将R1行舍弃。


    新的数据源:

               A         B         C         D         E   F
    R0  0.847803       NaN       NaN -0.407275  0.522512 NaN
    R1  1.566876 -1.370242  0.485341  0.351113  0.668934 NaN
    R2  0.183118       NaN       NaN  1.597792  0.969363 NaN
    R3  1.636157       NaN       NaN -0.854254 -0.720455 NaN
    R4  0.003340 -0.786744 -0.045098  1.248421  0.344938 NaN
    

    axis=1, how="any"舍弃含有Nan的列:

    # axis=1, how="any":舍弃含有Nan的列
    print(df.dropna(axis=1, how="any"))
    

    运行结果:

               A         D         E
    R0  0.847803 -0.407275  0.522512
    R1  1.566876  0.351113  0.668934
    R2  0.183118  1.597792  0.969363
    R3  1.636157 -0.854254 -0.720455
    R4  0.003340  1.248421  0.344938
    

    说明:由于df.dropna(axis=1, how="any")舍弃含有Nan的列,且数据源中,所有元素都为NaN的列是B、C、F,所以将B、C、F列舍弃,剩余A、D、E列。


    axis=1, how="all"舍弃某行元素都为Nan的列:

    # axis=1, how="all"舍弃某行元素都为Nan的列
    print(df.dropna(axis=1, how="all"))
    

    运行结果:

               A         B         C         D         E
    R0  0.847803       NaN       NaN -0.407275  0.522512
    R1  1.566876 -1.370242  0.485341  0.351113  0.668934
    R2  0.183118       NaN       NaN  1.597792  0.969363
    R3  1.636157       NaN       NaN -0.854254 -0.720455
    R4  0.003340 -0.786744 -0.045098  1.248421  0.344938
    

    说明:由于df.dropna(axis=1, how="all")舍弃某行元素都为Nan的列,且数据源中,所有元素都为NaN的列是F,所以将F列舍弃。


    • NaN填充数据

    DataFrame对象可以用fillna(value=1)对含有空元素的值进行重新赋值。

    数据源:

               A         B         C         D         E   F
    R0  0.150234       NaN       NaN -1.211939 -3.346958 NaN
    R1       NaN       NaN       NaN       NaN       NaN NaN
    R2  0.198726       NaN       NaN -0.235129  0.912252 NaN
    R3 -0.028627       NaN       NaN  0.028133 -0.419417 NaN
    R4  0.559427  1.249356  1.091567 -1.201653  0.797971 NaN
    
    print(df.fillna(value=1))
    

    运行结果:

               A         B         C         D         E    F
    R0  0.150234  1.000000  1.000000 -1.211939 -3.346958  1.0
    R1  1.000000  1.000000  1.000000  1.000000  1.000000  1.0
    R2  0.198726  1.000000  1.000000 -0.235129  0.912252  1.0
    R3 -0.028627  1.000000  1.000000  0.028133 -0.419417  1.0
    R4  0.559427  1.249356  1.091567 -1.201653  0.797971  1.0
    

    数据的合并

    Pandas对数据的合并提供了多种实现方式,最常用的有3种:pd.concat()、pd.append()、pd.merge()。下面将一一介绍:

    • pd.concat()方式

    pd.concat([df1, df2, df3,...],axis=0或1,ignore_index=True,join="outer"或者"inner", join_axes=[data1.index])

    参数说明:
    [df1, df2, df3,...]表示要合并的多个DataFrame对象组成的列表;
    axis=0或1分别表示在垂直方向合并还是在水平方向合并。
    ignore_index=True表示数据合并后重新排序索引,默认不重新排序索引。
    join="outer"或者"inner"outer表示向外括展,原来没有值得元素填充为NaN标记;inner表示向内收缩、取交集。只取公共行列的数据,其余的丢弃。
    join_axes=[df1.index]如果有join_axes的参数传入,可以指定根据那个轴来对齐数据。例如根据df1表对齐数据,就会保留指定的df1表的轴,然后将别的表与之拼接。

    axis=0垂直方向合并:

    import pandas as pd
    import numpy as np
    
    
    # 数据的合并
    
    index1 = pd.date_range("2018-10-01", periods=4)
    df1 = pd.DataFrame(np.arange(20).reshape((4, 5)), index=index1, columns=list("ABCDE"))
    print(df1)
    
    print("-" * 40)
    
    index2 = pd.date_range("2018-10-03", periods=3)
    df2 = pd.DataFrame(np.arange(12).reshape((3, 4)), index=index2, columns=list("DEFG"))
    print(df2)
    print("-" * 40)
    
    # concat
    # axis=0 垂直方向合并
    result = pd.concat([df1, df2], axis=0, sort=True)
    print(result)
    
    print("-" * 40)
    
    

    运行结果:

                 A   B   C   D   E
    2018-10-01   0   1   2   3   4
    2018-10-02   5   6   7   8   9
    2018-10-03  10  11  12  13  14
    2018-10-04  15  16  17  18  19
    ----------------------------------------
                D  E   F   G
    2018-10-03  0  1   2   3
    2018-10-04  4  5   6   7
    2018-10-05  8  9  10  11
    ----------------------------------------
                   A     B     C   D   E     F     G
    2018-10-01   0.0   1.0   2.0   3   4   NaN   NaN
    2018-10-02   5.0   6.0   7.0   8   9   NaN   NaN
    2018-10-03  10.0  11.0  12.0  13  14   NaN   NaN
    2018-10-04  15.0  16.0  17.0  18  19   NaN   NaN
    2018-10-03   NaN   NaN   NaN   0   1   2.0   3.0
    2018-10-04   NaN   NaN   NaN   4   5   6.0   7.0
    2018-10-05   NaN   NaN   NaN   8   9  10.0  11.0
    
    

    axis=1水平方向合并:

    # 上接
    # axis=1 水平方向合并
    result2 = pd.concat([df1, df2], axis=1)
    print(result2)
    

    运行结果:

                   A     B     C     D     E    D    E     F     G
    2018-10-01   0.0   1.0   2.0   3.0   4.0  NaN  NaN   NaN   NaN
    2018-10-02   5.0   6.0   7.0   8.0   9.0  NaN  NaN   NaN   NaN
    2018-10-03  10.0  11.0  12.0  13.0  14.0  0.0  1.0   2.0   3.0
    2018-10-04  15.0  16.0  17.0  18.0  19.0  4.0  5.0   6.0   7.0
    2018-10-05   NaN   NaN   NaN   NaN   NaN  8.0  9.0  10.0  11.0
    

    说明:上面例子在进行垂直方向合并时,行索引出现了如图结果,此时可以通过ignore_index=True对数据合并后要求重新排序索引,默认不重新排序索引的。

    image.png

    ignore_index=True表示数据合并后重新排序索引,默认不重新排序索引:

    # 上接
    # 忽略索引
    result3 = pd.concat([df1, df2], axis=0, ignore_index=True, sort=False)
    print(result3)
    

    运行结果:

          A     B     C   D   E     F     G
    0   0.0   1.0   2.0   3   4   NaN   NaN
    1   5.0   6.0   7.0   8   9   NaN   NaN
    2  10.0  11.0  12.0  13  14   NaN   NaN
    3  15.0  16.0  17.0  18  19   NaN   NaN
    4   NaN   NaN   NaN   0   1   2.0   3.0
    5   NaN   NaN   NaN   4   5   6.0   7.0
    6   NaN   NaN   NaN   8   9  10.0  11.0
    

    join="outer"或者"inner"outer表示向外括展,原来没有值得元素填充为NaN标记;inner表示向内收缩、取交集,只取公共行列的数据,其余的丢弃。join=默认取值outer

    # 上接
    # join=outer 默认
    result4 = pd.concat([df1, df2], axis=0, join="outer", sort=False)
    print(result4)
    
    # join=inner
    result5 = pd.concat([df1, df2], axis=0, join="inner", sort=False)
    print(result5)
    

    运行结果:

                   A     B     C   D   E     F     G
    2018-10-01   0.0   1.0   2.0   3   4   NaN   NaN
    2018-10-02   5.0   6.0   7.0   8   9   NaN   NaN
    2018-10-03  10.0  11.0  12.0  13  14   NaN   NaN
    2018-10-04  15.0  16.0  17.0  18  19   NaN   NaN
    2018-10-03   NaN   NaN   NaN   0   1   2.0   3.0
    2018-10-04   NaN   NaN   NaN   4   5   6.0   7.0
    2018-10-05   NaN   NaN   NaN   8   9  10.0  11.0
    
                 D   E
    2018-10-01   3   4
    2018-10-02   8   9
    2018-10-03  13  14
    2018-10-04  18  19
    2018-10-03   0   1
    2018-10-04   4   5
    2018-10-05   8   9
    
    • join_axes参数

    join_axes=[df1.index或df1.columns]如果有join_axes的参数传入,可以指定根据那个轴来对齐数据。例如根据df1表对齐数据,就会保留指定的df1表的轴,然后将别的表与之拼接。

    注意的是,此参数要和axis参数配合使用。如果axis=0,则如果有join_axes的参数传入,其值需要传入列索引才可以join_axes=[df1.columns]。反之,如果axis=1,则如果有join_axes的参数传入,其值需要传入行索引才可以join_axes=[df1.index]

    # 上接
    # axis=0, join_axes=[df1.columns]
    result6 = pd.concat([df1, df2], axis=0, join_axes=[df1.columns], sort=False)
    print(result6)
    
    # axis=1, join_axes=[df1.index]
    result7 = pd.concat([df1, df2], axis=1, join_axes=[df1.index], sort=False)
    print(result7)
    

    运行结果:

                   A     B     C   D   E
    2018-10-01   0.0   1.0   2.0   3   4
    2018-10-02   5.0   6.0   7.0   8   9
    2018-10-03  10.0  11.0  12.0  13  14
    2018-10-04  15.0  16.0  17.0  18  19
    2018-10-03   NaN   NaN   NaN   0   1
    2018-10-04   NaN   NaN   NaN   4   5
    2018-10-05   NaN   NaN   NaN   8   9
    
                 A   B   C   D   E    D    E    F    G
    2018-10-01   0   1   2   3   4  NaN  NaN  NaN  NaN
    2018-10-02   5   6   7   8   9  NaN  NaN  NaN  NaN
    2018-10-03  10  11  12  13  14  0.0  1.0  2.0  3.0
    2018-10-04  15  16  17  18  19  4.0  5.0  6.0  7.0
    

    说明:根据axis=, join_axes=[]入参不同,上面运行结果,分别保留了df1的列索引和行索引。

    • df.append()方式

    df1.append([df2, df2, df3,...],axis=0或1,ignore_index=True)
    参数说明:
    [df1, df2, df3,...]表示要合并的多个DataFrame对象组成的列表;
    axis=0或1分别表示在垂直方向合并还是在水平方向合并。
    ignore_index=True表示数据合并后重新排序索引,默认不重新排序索引。

    import pandas as pd
    import numpy as np
    
    
    # 数据的合并
    
    index1 = pd.date_range("2018-10-01", periods=4)
    df1 = pd.DataFrame(np.arange(20).reshape((4, 5)), index=index1, columns=list("ABCDE"))
    print(df1)
    
    print("-" * 40)
    
    index2 = pd.date_range("2018-10-03", periods=3)
    df2 = pd.DataFrame(np.arange(12).reshape((3, 4)), index=index2, columns=list("DEFG"))
    print(df2)
    print("-" * 40)
    
    
    result8 = df1.append(df2, ignore_index=True, sort=False)
    print(result8)
    

    运行结果:

                 A   B   C   D   E
    2018-10-01   0   1   2   3   4
    2018-10-02   5   6   7   8   9
    2018-10-03  10  11  12  13  14
    2018-10-04  15  16  17  18  19
    ----------------------------------------
                D  E   F   G
    2018-10-03  0  1   2   3
    2018-10-04  4  5   6   7
    2018-10-05  8  9  10  11
    ----------------------------------------
          A     B     C   D   E     F     G
    0   0.0   1.0   2.0   3   4   NaN   NaN
    1   5.0   6.0   7.0   8   9   NaN   NaN
    2  10.0  11.0  12.0  13  14   NaN   NaN
    3  15.0  16.0  17.0  18  19   NaN   NaN
    4   NaN   NaN   NaN   0   1   2.0   3.0
    5   NaN   NaN   NaN   4   5   6.0   7.0
    6   NaN   NaN   NaN   8   9  10.0  11.0
    

    说明:df.append()函数的入参含义、用法和concat()含义一样,此处不再赘述。

    • pd.merge()方式

    pd.merge(left, right, on=["key1", "key2"], how="inner", indicator="新索引说明")
    参数说明:
    left, right要参与合并的数据集;
    on=["key1", "key2"]依据指定的key进行合并,可以有多个key
    how="inner"或"outer"或"left"或"right"

    left:完全保留left数据,并基于此数据,把其他数据合并过来。
    right:完全保留right数据,并基于此数据,把其他数据合并过来。
    indicator="新索引说明"合并的过程,通过自定义新索引的方式提示出来。

    根据1个key合并"key",完整示例如下:

    import pandas as pd
    
    # 数据的合并
    
    left = pd.DataFrame({
        "key": ["A0", "A1", "A2", "A3"],
        "B": ["B0", "B1", "B2", "B3"],
        "C": ["C0", "C1", "C2", "C3"],
    
    })
    print(left)
    
    print("-" * 40)
    
    right = pd.DataFrame({
        "key": ["A0", "A1", "A2", "A3"],
        "D": ["B1", "B2", "B2", "B4"],
        "E": ["C2", "C1", "C5", "C2"]
    
    })
    print(right)
    print("-" * 40)
    # 根据1个key合并"key"
    result9 = pd.merge(left, right, on="key")
    print(result9)
    

    运行结果:

      key   B   C
    0  A0  B0  C0
    1  A1  B1  C1
    2  A2  B2  C2
    3  A3  B3  C3
    --------------------
      key   D   E
    0  A0  B1  C2
    1  A1  B2  C1
    2  A2  B2  C5
    3  A3  B4  C2
    --------------------
      key   B   C   D   E
    0  A0  B0  C0  B1  C2
    1  A1  B1  C1  B2  C1
    2  A2  B2  C2  B2  C5
    3  A3  B3  C3  B4  C2
    
    • 依据多个key的合并

    on=["key1", "key2"]依据指定的key进行合并,可以有多个key。要注意的是,这里合并依据的列举出的key,一定要在要合并的数据表中确实存在才可以,否则会报错。

    根据多个key合并,完整示例如下:

    import pandas as pd
    
    # 数据的合并
    
    left = pd.DataFrame({
        "key": ["A0", "A1", "A2", "A3"],
        "B": ["B0", "B1", "B2", "B3"],
        "C": ["C0", "C1", "C2", "C3"],
    })
    print(left)
    
    print("-" * 20)
    
    right = pd.DataFrame({
        "key": ["A0", "A1", "A2", "A3"],
        "B": ["B0", "B2", "B2", "B4"],
        "E": ["C2", "C1", "C5", "C2"]
    
    })
    print(right)
    print("-" * 20)
    
    # 根据多个key合并"key", "B"
    result9 = pd.merge(left, right, on=["key", "B"])
    
    print(result9)
    

    运行结果:

      key   B   C
    0  A0  B0  C0
    1  A1  B1  C1
    2  A2  B2  C2
    3  A3  B3  C3
    --------------------
      key   B   E
    0  A0  B0  C2
    1  A1  B2  C1
    2  A2  B2  C5
    3  A3  B4  C2
    --------------------
      key   B   C   E
    0  A0  B0  C0  C2
    1  A2  B2  C2  C5
    

    说明:这里合并的依据on=["key", "B"],两个数据表匹配的上的只有两行数据,就是上面打印的结果。

    • 合并模式how=

    how="inner"或"outer"或"left"或"right"

    left:完全保留left数据,并基于此数据,把其他数据合并过来。
    right:完全保留right数据,并基于此数据,把其他数据合并过来。示例如下:

    # how=默认值
    result9 = pd.merge(left, right, on=["key", "B"])
    print(result9)
    
    print("-" * 20)
    
    # how="left"
    result10 = pd.merge(left, right, on=["key", "B"], how="left")
    print(result10)
    
    print("-" * 20)
    
    # how="right"
    result11 = pd.merge(left, right, on=["key", "B"], how="right")
    print(result11)
    

    运行结果:

      key   B   C   E
    0  A0  B0  C0  C2
    1  A2  B2  C2  C5
    --------------------
      key   B   C    E
    0  A0  B0  C0   C2
    1  A1  B1  C1  NaN
    2  A2  B2  C2   C5
    3  A3  B3  C3  NaN
    --------------------
      key   B    C   E
    0  A0  B0   C0  C2
    1  A2  B2   C2  C5
    2  A1  B2  NaN  C1
    3  A3  B4  NaN  C2
    

    数据的导出和导入

    数据的导出和导入,支持多种格式csv、json、html等等,如下图:

    导出选项

    我们此处只随便选取2种举例,示例如下:

    import pandas as pd
    
    # 数据的导出和导入
    
    
    left = pd.DataFrame({
        "key": ["A0", "A1", "A2", "A3"],
        "B": ["B0", "B1", "B2", "B3"],
        "C": ["C0", "C1", "C2", "C3"],
    
    })
    
    # 导出csv格式
    left.to_csv("left_data.csv")
    
    # 导出json格式
    left.to_json("left.json")
    

    运行结果:

    导出为csv格式和json格式

    说明:运行后,如果没有特别指定路径,则默认会在当前模块下生产对应的格式的文件。

    数据画图

    绘制图像,需要使用到matplotlib模块,绘图分为plt.plot(xxx)、plt.show()关键步骤。需要注意的是,此处我们可以直接用result.plot(),是因为result经过累加计算,已是数据了,可以直接用来绘制,然后调用plt.show()显示出图像即可。

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 生产1000个数据
    s = pd.Series(np.random.randn(1000))
    
    # 累加求和
    result = s.cumsum()
    
    # 绘制
    result.plot()
    
    # 显示图像
    plt.show()
    

    运行结果:


    pandas绘图

    小结

    Pandas是基于NumPy的,两者是数据分析强大的工具。熟练掌握,对以后数据处理很有帮助。

    相关文章

      网友评论

        本文标题:44.Python编程:Pandas详解

        本文链接:https://www.haomeiwen.com/subject/tjafaftx.html