zoukankan      html  css  js  c++  java
  • Python 数据处理库 pandas

    核心数据结构

    pandas最核心的就是SeriesDataFrame两个数据结构。

    名称维度说明
    Series 1维 带有标签的同构类型数组
    DataFrame 2维 表格结构,带有标签,大小可变,且可以包含异构的数据列

    DataFrame可以看做是Series的容器,即:一个DataFrame中可以包含若干个Series。

    series

    由于Series是一堆结构的数据,我们可以直接通过数组来创建这种数据,像这样:

    import pandas as pd
    import numpy as np
     
    series1 = pd.Series([1, 2, 3, 4])
    print("series1:
    {}
    ".format(series1))
    
    # series1:
    # 0    1
    # 1    2
    # 2    3
    # 3    4
    # dtype: int64
    • 输出的最后一行是Series中数据的类型,这里的数据都是int64类型的。
    • 数据在第二列输出,第一列是数据的索引

    我们分别打印出Series中的数据和索引

    print("series1.values: {}
    ".format(series1.values))
     
    print("series1.index: {}
    ".format(series1.index))
    
    # series1.values: [1 2 3 4]
    # series1.index: RangeIndex(start=0, stop=4, step=1)

    我们可以指定索引的类型,例如字符串

    series2 = pd.Series([1, 2, 3, 4, 5, 6, 7],
    index=["C", "D", "E", "F", "G", "A", "B"])
    print("series2:
    {}
    ".format(series2))
    print("E is {}
    ".format(series2["E"]))
    
    # series2:
    # C    1
    # D    2
    # E    3
    # F    4
    # G    5
    # A    6
    # B    7
    # dtype: int64
    
    # E is 3

    DataFrame

    通过Numpy接口来创建一个4x4的矩阵,以此来创建DataFrame

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df1 = pd.DataFrame(np.arange(16).reshape(4,4))
     5 print("df1:
    {}
    ".format(df1))
     6 
     7 # df1:
     8 #     0   1   2   3
     9 # 0   0   1   2   3
    10 # 1   4   5   6   7
    11 # 2   8   9  10  11
    12 # 3  12  13  14  15
    View Code

    默认的索引和列名都是[0,N-1]的形式,同样我们可以指定列名和索引,

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df2 = pd.DataFrame(np.arange(16).reshape(4,4),
     5 columns=["column1", "column2", "column3", "column4"],
     6 index=["a", "b", "c", "d"])
     7 print("df2:
    {}
    ".format(df2))
     8 
     9 # df2:
    10 #    column1  column2  column3  column4
    11 # a        0        1        2        3
    12 # b        4        5        6        7
    13 # c        8        9       10       11
    14 # d       12       13       14       15
    View Code

    我们也可以指定结构来创建DataFrame

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df3 = pd.DataFrame({"note" : ["C", "D", "E", "F", "G", "A", "B"],
     5     "weekday": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]})
     6 print("df3:
    {}
    ".format(df3))
     7 
     8 # df3:
     9 #   note weekday
    10 # 0    C     Mon
    11 # 1    D     Tue
    12 # 2    E     Wed
    13 # 3    F     Thu
    14 # 4    G     Fri
    15 # 5    A     Sat
    16 # 6    B     Sun
    View Code

    注意:

    • DataFrame的不同列可以是不同的数据类型

    • 如果以Series数组来创建DataFrame,每个Series将成为一行,而不是一列

     1 import pandas as pd
     2 import numpy as np
     3  
     4 noteSeries = pd.Series(["C", "D", "E", "F", "G", "A", "B"],
     5     index=[1, 2, 3, 4, 5, 6, 7])
     6 weekdaySeries = pd.Series(["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
     7     index=[1, 2, 3, 4, 5, 6, 7])
     8 df4 = pd.DataFrame([noteSeries, weekdaySeries])
     9 print("df4:
    {}
    ".format(df4))
    10 
    11 # df4:
    12 #      1    2    3    4    5    6    7
    13 # 0    C    D    E    F    G    A    B
    14 # 1  Mon  Tue  Wed  Thu  Fri  Sat  Sun
    View Code

    我们还可以“添加”或“删除”列数据

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df3 = pd.DataFrame({"note" : ["C", "D", "E", "F", "G", "A", "B"],
     5                     "weekday": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]})
     6 df3["No."] = pd.Series([1, 2, 3, 4, 5, 6, 7])
     7 print("df3:
    {}
    ".format(df3))
     8  
     9 del df3["weekday"]
    10 print("df3:
    {}
    ".format(df3))
    11 
    12 # df3:
    13 #   note weekday  No.
    14 # 0    C     Mon    1
    15 # 1    D     Tue    2
    16 # 2    E     Wed    3
    17 # 3    F     Thu    4
    18 # 4    G     Fri    5
    19 # 5    A     Sat    6
    20 # 6    B     Sun    7
    21 
    22 # df3:
    23 #   note  No.
    24 # 0    C    1
    25 # 1    D    2
    26 # 2    E    3
    27 # 3    F    4
    28 # 4    G    5
    29 # 5    A    6
    30 # 6    B    7
    View Code

    index对象与数据访问

    同样可以通过索引来获取DataFrame的行和列

    1 print("df3.columns
    {}
    ".format(df3.columns))
    2 print("df3.index
    {}
    ".format(df3.index))
    3 
    4 # df3.columns
    5 # Index(['note', 'No.'], dtype='object')
    6 
    7 # df3.index
    8 # RangeIndex(start=0, stop=7, step=1)
    View Code

    注意:

    • Index并非集合,因此其中可以包含重复的数据

    • Index对象的值是不可以改变,因此可以通过它安全的访问数据

    DataFrane提供了下面两个操作符来访问其中的数据

    • loc:通过行和列的索引来访问数据

    • iloc:通过行和列的下标来访问数据

     1 print("Note C, D is:
    {}
    ".format(df3.loc[[0, 1], "note"]))
     2 print("Note C, D is:
    {}
    ".format(df3.iloc[[0, 1], 0]))
     3 
     4 # Note C, D is:
     5 # 0    C
     6 # 1    D
     7 # Name: note, dtype: object
     8 
     9 # Note C, D is:
    10 # 0    C
    11 # 1    D
    12 # Name: note, dtype: object
    View Code

    第一行代码访问了行索引为0和1,列索引为“note”的元素,第二行代码访问了行下标为0和1对于df3来说,行索引和行下标刚好是一样的,所以这里都是0和1,但它们却是不同的含义),列下标为0的元素。

    文件操作

    读取Excel文件

    注:要读取Excel文件,还需要安装另外一个库;xlrd

    pip install xlrd

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df1 = pd.read_excel("data/test.xlsx")
     5 print("df1:
    {}
    ".format(df1))
     6 
     7 # df1:
     8 #    C  Mon
     9 # 0  D  Tue
    10 # 1  E  Wed
    11 # 2  F  Thu
    12 # 3  G  Fri
    13 # 4  A  Sat
    14 # 5  B  Sun
    View Code

     读取csv文件

    1 C,Mon
    2 D,Tue
    3 E,Wed
    4 F,Thu
    5 G,Fri
    6 A,Sat
    第一个CSV文件内容
    1 C|Mon
    2 D|Tue
    3 E|Wed
    4 F|Thu
    5 G|Fri
    6 A|Sat
    第二个CSV文件的内容

    读取CSV文件

    1 import pandas as pd
    2 import numpy as np
    3 df2 = pd.read_csv("data/test1.csv")
    4 print("df2:
    {}
    ".format(df2))
    5 # df3 = pd.read_csv("data/test2.csv", sep="|")
    6 # print("df3:
    {}
    ".format(df3))
    View Code

    我们可以发现,第二个CSV文件并不是通过逗号分隔的,我们通常指定分隔符的方式来读取这个文件。

    read_csv支持非常多的参数用来调整读取的参数

    参数说明
    path 文件路径
    sep或者delimiter 字段分隔符
    header 列名的行数,默认是0(第一行)
    index_col 列号或名称用作结果中的行索引
    names 结果的列名称列表
    skiprows 从起始位置跳过的行数
    na_values 代替NA的值序列
    comment 以行结尾分隔注释的字符
    parse_dates 尝试将数据解析为datetime。默认为False
    keep_date_col 如果将列连接到解析日期,保留连接的列。默认为False
    converters 列的转换器
    dayfirst 当解析可以造成歧义的日期时,以内部形式存储。默认为False
    data_parser 用来解析日期的函数
    nrows 从文件开始读取的行数
    iterator 返回一个TextParser对象,用于读取部分内容
    chunksize 指定读取块的大小
    skip_footer 文件末尾需要忽略的行数
    verbose 输出各种解析输出的信息
    encoding 文件编码
    squeeze 如果解析的数据只包含一列,则返回一个Series
    thousands 千数量的分隔符

    详细的read_csv函数说明请参见这里:pandas.read_csv

    处理无效值

    主要有两种处理方法:直接忽略这些无效值;或者将无效值替换成有效值。

    我们先创建一个包含无效值的数据结构。然后通过pandas.isna函数来确认哪些值是无效的:

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],
     5                   [5.0, np.nan, np.nan, 8.0],
     6                   [9.0, np.nan, np.nan, 12.0],
     7                   [13.0, np.nan, 15.0, 16.0]])
     8  
     9 print("df:
    {}
    ".format(df));
    10 print("df:
    {}
    ".format(pd.isna(df)))
    11 
    12 # df:
    13 #       0   1     2     3
    14 # 0   1.0 NaN   3.0   4.0
    15 # 1   5.0 NaN   NaN   8.0
    16 # 2   9.0 NaN   NaN  12.0
    17 # 3  13.0 NaN  15.0  16.0
    18  
    19 # df:
    20 #        0     1      2      3
    21 # 0  False  True  False  False
    22 # 1  False  True   True  False
    23 # 2  False  True   True  False
    24 # 3  False  True  False  False
    View Code

    忽略无效值

    我们可以通过pandas.DataFrame.dropna函数抛弃无效值

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],
     5                   [5.0, np.nan, np.nan, 8.0],
     6                   [9.0, np.nan, np.nan, 12.0],
     7                   [13.0, np.nan, 15.0, 16.0]])
     8  
     9 print("df.dropna():
    {}
    ".format(df.dropna()));
    10 
    11 # df.dropna():
    12 # Empty DataFrame
    13 # Columns: [0, 1, 2, 3]
    14 # Index: []
    View Code

    对于原先的结构,当无效值全部被抛弃之后,将不再是一个有效的DataFrame,所以才会是以上结果

    我们也可以选择抛弃整列都是无效值的那一列:

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],
     5                   [5.0, np.nan, np.nan, 8.0],
     6                   [9.0, np.nan, np.nan, 12.0],
     7                   [13.0, np.nan, 15.0, 16.0]])
     8  
     9 print("df.dropna(axis=1,how='all'):
    {}
    ".format(df.dropna(axis=1, how='all')));
    10 
    11 # df.dropna(axis=1, how='all'):
    12 #       0     2     3
    13 # 0   1.0   3.0   4.0
    14 # 1   5.0   NaN   8.0
    15 # 2   9.0   NaN  12.0
    16 # 3  13.0  15.0  16.0
    View Code

    注:axis=1表示列的轴。how可以取值’any’或者’all’,默认是前者。

    替换无效值

    我们也可以通过fillna函数将无效值替换成为有效值

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],
     5                   [5.0, np.nan, np.nan, 8.0],
     6                   [9.0, np.nan, np.nan, 12.0],
     7                   [13.0, np.nan, 15.0, 16.0]])
     8  
     9 print("df:
    {}
    ".format(df));
    10 
    11 print("df.fillna(1):
    {}
    ".format(df.fillna(1)));
    12 
    13 # df:
    14 #       0   1     2     3
    15 # 0   1.0 NaN   3.0   4.0
    16 # 1   5.0 NaN   NaN   8.0
    17 # 2   9.0 NaN   NaN  12.0
    18 # 3  13.0 NaN  15.0  16.0
    19 
    20 # df.fillna(1):
    21 #       0    1     2     3
    22 # 0   1.0  1.0   3.0   4.0
    23 # 1   5.0  1.0   1.0   8.0
    24 # 2   9.0  1.0   1.0  12.0
    25 # 3  13.0  1.0  15.0  16.0
    View Code

    将无效值全部替换成同样的数据可能意义不大,因此我们可以指定不同的数据来进行填充。为了便于操作,在填充之前,我们可以先通过rename方法修改行和列的名称:

     1 import pandas as pd
     2 import numpy as np
     3  
     4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],
     5                   [5.0, np.nan, np.nan, 8.0],
     6                   [9.0, np.nan, np.nan, 12.0],
     7                   [13.0, np.nan, 15.0, 16.0]])
     8  
     9 print("df:
    {}
    ".format(df));
    10 print("df:
    {}
    ".format(pd.isna(df)))
    11 
    12 df.rename(index={0: 'index1', 1: 'index2', 2: 'index3', 3: 'index4'},
    13           columns={0: 'col1', 1: 'col2', 2: 'col3', 3: 'col4'},
    14           inplace=True);
    15 df.fillna(value={'col2': 2}, inplace=True)  # 把第2列的空值变成2
    16 df.fillna(value={'col3': 7}, inplace=True)  # 把第3列的空值变成7
    17 print("df:
    {}
    ".format(df));
    18 
    19 # df:
    20 #       0   1     2     3
    21 # 0   1.0 NaN   3.0   4.0
    22 # 1   5.0 NaN   NaN   8.0
    23 # 2   9.0 NaN   NaN  12.0
    24 # 3  13.0 NaN  15.0  16.0
    25 
    26 # df:
    27 #        0     1      2      3
    28 # 0  False  True  False  False
    29 # 1  False  True   True  False
    30 # 2  False  True   True  False
    31 # 3  False  True  False  False
    32 
    33 # df:
    34 #         col1  col2  col3  col4
    35 # index1   1.0   2.0   3.0   4.0
    36 # index2   5.0   2.0   7.0   8.0
    37 # index3   9.0   2.0   7.0  12.0
    38 # index4  13.0   2.0  15.0  16.0
    View Code

    处理字符串

    Seriesstr字段包含了一系列的函数用来处理字符串。并且,这些函数会自动处理无效值。

     1 import pandas as pd
     2  
     3 s1 = pd.Series([' 1', '2 ', ' 3 ', '4', '5']);
     4 print("s1.str.rstrip():
    {}
    ".format(s1.str.lstrip()))
     5 print("s1.str.strip():
    {}
    ".format(s1.str.strip()))
     6 print("s1.str.isdigit():
    {}
    ".format(s1.str.isdigit()))
     7 
     8 # s1.str.rstrip():
     9 # 0     1
    10 # 1    2 
    11 # 2    3 
    12 # 3     4
    13 # 4     5
    14 # dtype: object
    15 
    16 # s1.str.strip():
    17 # 0    1
    18 # 1    2
    19 # 2    3
    20 # 3    4
    21 # 4    5
    22 # dtype: object
    23 
    24 # s1.str.isdigit():
    25 # 0    False
    26 # 1    False
    27 # 2    False
    28 # 3     True
    29 # 4     True
    30 # dtype: bool
    View Code

    我们还能对字符串进行大写、小写、以及字符串长度的处理。

     1 import pandas as pd
     2  
     3 s2 = pd.Series(['Stairway to Heaven', 'Eruption', 'Freebird',
     4                     'Comfortably Numb', 'All Along the Watchtower'])
     5 print("s2.str.lower():
    {}
    ".format(s2.str.lower()))
     6 print("s2.str.upper():
    {}
    ".format(s2.str.upper()))
     7 print("s2.str.len():
    {}
    ".format(s2.str.len()))
     8 
     9 # s2.str.lower():
    10 # 0          stairway to heaven
    11 # 1                    eruption
    12 # 2                    freebird
    13 # 3            comfortably numb
    14 # 4    all along the watchtower
    15 # dtype: object
    16 
    17 # s2.str.upper():
    18 # 0          STAIRWAY TO HEAVEN
    19 # 1                    ERUPTION
    20 # 2                    FREEBIRD
    21 # 3            COMFORTABLY NUMB
    22 # 4    ALL ALONG THE WATCHTOWER
    23 # dtype: object
    24 
    25 # s2.str.len():
    26 # 0    18
    27 # 1     8
    28 # 2     8
    29 # 3    16
    30 # 4    24
    31 # dtype: int64
    View Code

    参考文献

    https://paul.pub/pandas-tutorial/

  • 相关阅读:
    替换gitlab自带的Nginx,并修改仓库存储路径
    linux 内网scp 无密码传输
    centos7 安装docker及Hyperf
    VMware 安装centos 7 及自动挂载共享文件夹
    基于 Thrift + Laravel RPC 调用实现
    PHP计算两个经纬度地点之间的距离
    sql server 2008安装过程中服务器配置出错
    SQL Server2008如何设置开启远程连接
    向上下左右不间断无缝滚动图片的效果(兼容火狐和IE)
    彻底解决Google浏览器CSS居中问题
  • 原文地址:https://www.cnblogs.com/LXP-Never/p/9696104.html
Copyright © 2011-2022 走看看