美文网首页Python Pandas
Python Pandas学习笔记。 vol4. 2019031

Python Pandas学习笔记。 vol4. 2019031

作者: 女程序员April | 来源:发表于2019-11-28 10:54 被阅读0次

    本文章仅供我本人学习记录使用,不允许任何转载及引用。特此声明。


    Pandas是建立在Numpy的基础上的,处理二维数据时更加得心应手。
    Pandas增加了更多高级使用的功能,比如数据自动对齐功能,时间序列的支持,确实数据的灵活处理等等。

    In[1]: import pandas as pd
    In[2]: import bumpy as np
    In[3]: from pandas import Series, DataFrame
    

    Series 和 DataFrame

    是Pandas的两种核心数据结构。

    Series:

    Series是值的序列,可以理解为一维数组,它只有一个列和索引。
    索引可以定制,当不指定时默认使用整数索引,而且索引可以被命名:

    In[1]:s1 = Series([1, 2, 3, 4, 5]) 
    Out[1]: 
    0    1
    1    2
    2    3
    3    4
    4    5
    dtype: int64
    # 第一列是未指定时默认的整数索引
    
    In[2]: s2 = Series([1, 2, 3, 4, 5], index = ['a', 'b', 'c', 'd', 'e'])
    Out[2]: 
    a    1
    b    2
    c    3
    d    4
    e    5
    dtype: int64
    # 定制索引时
    
    In[3]: s2.index.name = 'index'
    
    In[4]: s2.index
    Out[4]: Index(['a', 'b', 'c', 'd', 'e'], dtype='object', name='index')
    
    In[5]: s2
    Out[5]:
    index
    a    1
    b    2
    c    3
    d    4
    e    5
    dtype: int64
    

    DataFrame:

    DataFrame类似于二维数组,有行和列之分,除了像Series一样,多个行有索引之外,每个列上面还可以有标签label,索引和标签本身都可以被命名:

    In[1]: df = DataFrame(np.random.randn(4, 4), index = ['a', 'b', 'c', 'd'], columns = ['A', 'B', 'C', 'D'])
    Out[1]: 
              A         B         C         D
    a -0.877290  0.434619 -0.996634 -0.398794
    b  1.131611 -1.553991 -0.696632 -0.209264
    c  0.785401 -0.967436 -0.063710 -0.442142
    d  0.045040 -0.446373  1.835974  0.820756
    # index和columns的设置也可以用index = list('abc')
    
    In[2]: df.index
    Out[2]: Index(['a', 'b', 'c', 'd'], dtype='object')
    
    In[3]: df.index.name = 'Index1'
    Out[3]: Index(['a', 'b', 'c', 'd'], dtype='object', name='Index1')
    
    In [4]: df.columns
    Out[4]: Index(['A', 'B', 'C', 'D'], dtype='object')
    
    In[5]: df.columns.name = 'Col'
    Out[5]: Index(['A', 'B', 'C', 'D'], dtype='object', name='Col')
    
    In[6]: df
    Out[6]: 
    Col            A         B         C         D
    Index1
    a      -0.877290  0.434619 -0.996634 -0.398794
    b       1.131611 -1.553991 -0.696632 -0.209264
    c       0.785401 -0.967436 -0.063710 -0.442142
    d       0.045040 -0.446373  1.835974  0.820756
    
    # ***行列转换***
    In[]: df.T
    

    选择

    当需要选择部分数据时:

    • Series:

    主要通过其索引来进行选择:

    In[1]: s2 = Series([1, 2, 3, 4, 5], index = ['a', 'b', 'c', 'd', 'e'])
    Out[1]: 
    a    1
    b    2
    c    3
    d    4
    e    5
    dtype: int64
    
    In[2]: s2[0]
    Out[2]: 1
    # 默认整数索引,一直存在的
    
    In[3]: s2['a']
    Out[3]: 1
    # 指定后的索引
    
    In[4]: s2[0:3]
    Out[4]: 
    a    1
    b    2
    c    3
    dtype: int64
    
    In[5]: s2['a':'c']
    Out[5]: 
    a    1
    b    2
    c    3
    dtype: int64
    

    以上调用多行,使用了s2.N和s2.loc。

    • s2[0:3]相当于s2.iloc[0:3],
    • s2['a':'c']相当于s2.loc['a':'c'],
    • 不能互换
      如下:
    In[6]: s2.iloc[0:3]
    Out[6]: 
    a    1
    b    2
    c    3
    dtype: int64
    
    In[7]: s2.loc['a':'c']
    Out[7]: 
    a    1
    b    2
    c    3
    dtype: int64
    
    通过步长,用 iloc [[[间隔调用多行]]]:
    In []: s2.iloc[::2]
    Out[]:
    a    1
    c    3
    e    5
    dtype: int64
    
    方法一:iloc[::5] 方法二:index.isin()

    .iloc和.loc和.ix的区别进阶学习:
    .ix:(https://fishc.com.cn/thread-79821-1-1.html)
    区别:(https://blog.csdn.net/hecongqing/article/details/61927615

    • DataFrame:

    由于有行列之分,所以可以有多种选择数据的方式:
    -- 通过索引或标签来选择:

    (1) 用标签(列)选择:
    In[8]: df
    Out[8]: 
              A         B         C         D
    a -1.219787  0.730984 -0.785763 -0.634453
    b -0.317280 -1.279367  0.359007  0.700775
    c -2.226339  0.380315  2.120930 -1.161018
    d -1.212816 -0.777530 -0.130212  1.492688
    
    In[9]: df.A
    Out[9]: 
    a   -1.219787
    b   -0.317280
    c   -2.226339
    d   -1.212816
    Name: A, dtype: float64
    
    In[10]: df['A']
    Out[10]: 
    a   -1.219787
    b   -0.317280
    c   -2.226339
    d   -1.212816
    Name: A, dtype: float64
    # 使用标签,df.A和df['A']相同,可以选择某1列
    
    # 使用标签,选择多列:
    In[11]: df[df.columns[0:2]]
    Out[11]: 
              A         B
    a -1.219787  0.730984
    b -0.317280 -1.279367
    c -2.226339  0.380315
    d -1.212816 -0.777530
    # 只能使用默认整数索引
    # 或者df.loc[:, ['A':'B']],下面有演示
    

    ---查看列名:

    In[]: df.columns.tolist()
    Out[]:
    

    ---删除列或删除行:

    In[]: 
    df.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')    
    # 例:
    In[]: 
    df.drop((0, 'b_amt'), axis=1)
    # (0, 'b_amt')就是一个列名,不用加‘’或()或[]
    
    # 或 
    In[]:
    df.drop(['B', 'C'], axis=1)
    # 或 
    In[]: 
    df.drop(index='cow', columns='small')
    # Drop a row by index:
    In[]: 
    df.drop([0, 1])
    

    ---重命名列columns:

    In[]:
    df.rename(columns={'A':'a', 'B':'b'})
    
    (2).选择‘行’:

    使用loc和iloc选择一行或多行

    
    In[12]: df
    Out[12]: 
              A         B         C         D
    a -1.219787  0.730984 -0.785763 -0.634453
    b -0.317280 -1.279367  0.359007  0.700775
    c -2.226339  0.380315  2.120930 -1.161018
    d -1.212816 -0.777530 -0.130212  1.492688
    
    In[13]: df.loc['a']
    Out[13]: 
    A   -1.219787
    B    0.730984
    C   -0.785763
    D   -0.634453
    Name: a, dtype: float64
    # df.iloc[0]有同样效果
    
    In[14]: df.loc['a':'b']
    Out[14]: 
              A         B         C         D
    a -1.219787  0.730984 -0.785763 -0.634453
    b -0.317280 -1.279367  0.359007  0.700775
    
    # 用loc和iloc选择列:
    In[15]: df.loc[:, 'A':'B']
    Out[15]: 
              A         B
    a -1.219787  0.730984
    b -0.317280 -1.279367
    c -2.226339  0.380315
    d -1.212816 -0.777530
    # 相当于用‘:’同时选择所有行,并在所有列中选择某几列。
    
    # 由此知道,选择某一行某一列的一个元素,或某几行或某几列的多个元素就简单了:
    In[16]: df
    Out[16]: 
              A         B         C         D
    a -1.219787  0.730984 -0.785763 -0.634453
    b -0.317280 -1.279367  0.359007  0.700775
    c -2.226339  0.380315  2.120930 -1.161018
    d -1.212816 -0.777530 -0.130212  1.492688
    
    In[17]: df.loc['a', 'A']
    Out[17]: -1.2197869779119481
    # df.iloc[0, 0],效果相同
    
    In[18]: df.loc['b':'c', 'C':'D']
    Out[18]: 
              C         D
    b  0.359007  0.700775
    c  2.120930 -1.161018
    # df.iloc[1:3, 2:4], 效果相同
    
    # ***隔列选择***
    df[['A','D']]  
    #选择表格中的'w'、'z'列
    #更多请查看:https://blog.csdn.net/wanglingli95/article/details/78887771
    

    缺失值'NaN'和数据自动对齐

    在Pandas中最重要的一个功能是,它可以对不同索引的对象进行算术运算。比如将两个Series数据进行相加时,如果存在不同的索引,则结果是两个索引的并集, 示例如下:

    In[1]: s1 = Series([1, 2, 3, 4], index = ['a', 'b', 'c', 'd'])
    
    In[2]: s1
    Out[2]: 
    a    1
    b    2
    c    3
    d    4
    dtype: int64
    
    In[3]: s2 = Series([2, 3, 4, 5], index = ['b', 'c', 'd', 'e'])
    Out[3]: 
    b    2
    c    3
    d    4
    e    5
    dtype: int64
    
    In[4]: s1 + s2
    Out[4]: 
    a    NaN
    b    4.0
    c    6.0
    d    8.0
    e    NaN
    dtype: float64
    # 两个索引的并集
    

    2个Series中['b', 'c', 'd']的索引是相同的,所以值可以相加,但不重叠的索引引入了NaN值(缺失值)。
    而缺失值会在运算中传播,所以最终结果也是NaN值。(后面会讲解)
    根据相同的索引进行自动计算,这就是自动对齐功能。

    在DataFrame中,相同的规格也生效:

    In[5]: df1 = DataFrame(np.arange(9).reshape(3, 3), columns = list('ABC'), index = list('abc'))
    Out[5]: 
       A  B  C
    a  0  1  2
    b  3  4  5
    c  6  7  8
    
    In[6]: df2 = DataFrame(np.arange(12).reshape(3,
        ...: 4), index = list('bcd'), columns = list('
        ...: ABDE'))
    Out[6]: 
       A  B   D   E
    b  0  1   2   3
    c  4  5   6   7
    d  8  9  10  11
    
    In[7]: df1 + df2
    Out[7]: 
          A     B   C   D   E
    a   NaN   NaN NaN NaN NaN
    b   3.0   5.0 NaN NaN NaN
    c  10.0  12.0 NaN NaN NaN
    d   NaN   NaN NaN NaN NaN
    

    可以看出,DataFrame的计算也进行了自动对齐操作,NaN值被自动填充,而由于NaN值会传播(如上解释),所以相加的结果也是NaN。
    如果我们想避免结果为NaN值,可以指定使用值来填充(替代)NaN值,如下:

    In[8]: df1.add(df2, fill_value = 0)
    Out[8]: 
          A     B    C     D     E
    a   0.0   1.0  2.0   NaN   NaN
    b   3.0   5.0  5.0   2.0   3.0 
    c  10.0  12.0  8.0   6.0   7.0
    d   8.0   9.0  NaN  10.0  11.0
    # 使用fill_value参数指定NaN值的填充值,使用与Series和DataFrame。
    

    我们指定了‘0’填充了NaN值,然后带入计算过程(这里是先填充值,再运算)。
    这里剩余的NaN值是因为df1和df2中都未定义。

    常用运算

    Series和DataFrame的常用运算和Numpy差不多。
    在Pandas中还有一种比较常见的操作时将函数运用到每一行或者每一列上面,DataFrame的apply方法可以实现此功能,比如想统计每行和每列的极差(最大值和最小值之差):

    In[1]: df1 = DataFrame(np.arange(9).reshape(3, 3
        ...: ), index = list('abc'), columns = list('A
        ...: BC'))
    
    In[2]: df1
    Out[2]: 
       A  B  C
    a  0  1  2
    b  3  4  5
    c  6  7  8
    
    In[3]: f = lambda x: x.max() - x.min()
    # 定义了f,f是匿名函数
    
    In [4]: f
    Out[4]: <function __main__.<lambda>>
    # f匿名函数简单的返回列表的极差
    
    In[5]: df1.apply(f)
    Out[5]: 
    A    6
    B    6
    C    6
    dtype: int64
    # 将计算极差的匿名函数f使用apply方法应用到df1上
    
    In [6]: df1.apply(f, axis = 1)
    Out[6]:
    a    2
    b    2
    c    2
    dtype: int64
    # 这个加入了参数axis = 1,所以计算df1中每一行的极差(索引‘a’行中max最大值‘2’和min最小值‘0’之差是2)
    # 上一个计算中,默认的axis是0(列),所以计算的是每一列的极差(索引‘A’列中max最大值‘6’和min最小值‘0’之差是6)
    

    如果想将某函数应用到每一个元素上,DataFrame可以使用df.applymap方法,Series可以使用s.map方法:

    In [7]: df1.applymap(lambda x: x + 1)
    Out[7]:
       A  B  C
    a  1  2  3
    b  4  5  6
    c  7  8  9
    
    In [8]: s1
    Out[8]:
    a    1
    b    2
    c    3
    d    4
    dtype: int64
    
    In [9]: s1.map(lambda x: x + 1)
    Out[9]:
    a    2
    b    3
    c    4
    d    5
    dtype: int64
    # 以上结果是让所有元素增加1,其结果与df1 + 1和s1 + 1的运算结果相同。
    

    常用统计:

    比如求平均值,方差等,同时通过describe方法可以得知当前数据的一些常用统计信息:

    In[]: df1 = DataFrame(np.arange(9).reshape(3,3), columns=list('ABC'), index=list('abc'))
    
    In[]: df1
    Out[]: 
       A  B  C
    a  0  1  2
    b  3  4  5
    c  6  7  8
    
    In[]: df1.sum()
    Out[]: 
    A     9
    B    12
    C    15
    dtype: int64
    # 每列求和
    
    In[]: df1.sum(axis = 1)
    Out[]:
    a     3
    b    12
    c    21
    dtype: int64
    # 每行求和
    
    In[]: df1.mean()
    Out[]:
    A    3.0
    B    4.0
    C    5.0
    dtype: float64
    # 每列的平均数
    
    In []: df1.mean(axis = 1)
    Out[]:
    a    1.0
    b    4.0
    c    7.0
    dtype: float64
    # 每行的平均数
    
    In[]: df1.describe()
    Out[]: 
             A    B    C
    count  3.0  3.0  3.0 # 列的元素的数量
    mean   3.0  4.0  5.0 # 列的平均值
    std    3.0  3.0  3.0 # 列的标准差
    min    0.0  1.0  2.0 # 列的最小值(0%)
    25%    1.5  2.5  3.5 # 下四分位数
    50%    3.0  4.0  5.0 # 中位数
    75%    4.5  5.5  6.5 # 上四分位数
    max    6.0  7.0  8.0 # 列的最大值(100%)
    
    In[]: df1.loc['b'].describe()
    Out[]:
    count    3.0
    mean     4.0
    std      1.0
    min      3.0
    25%      3.5
    50%      4.0
    75%      4.5
    max      5.0
    Name: b, dtype: float64
    # 第二行'b'行的统计信息
    # *目前还不知道怎么统计多行信息*
    

    数据合并和分组

    合并2个DataFrame数据,方法主要有2种:
    (1)简单进行拼接,通过pd.concat方法实现
    (2)根据列名类像数据库表查询一样进行合并,通过pd.merge方法实现

    In[]: df1 = DataFrame(np.random.randn(3, 3))
    
    In[]: df2 = DataFrame(np.random.randn(3, 3), index = [5, 6, 7])
    
    In[]: df1
    Out[]: 
              0         1         2
    0 -2.072551 -1.759958  0.465906
    1 -1.302374  2.343270  0.233606
    2 -1.450751  1.160754  1.271709
    
    In[]: df2
    Out[]: 
              0         1         2
    5  0.092593  1.846336  1.757417
    6  0.328430 -1.662719 -0.366255
    7 -0.360098 -0.334050 -0.032662
    
    In[]: pd.concat([df1, df2])
    Out[]: 
              0         1         2
    0 -2.072551 -1.759958  0.465906
    1 -1.302374  2.343270  0.233606
    2 -1.450751  1.160754  1.271709
    5  0.092593  1.846336  1.757417
    6  0.328430 -1.662719 -0.366255
    7 -0.360098 -0.334050 -0.032662
    # 当多个数据集,拥有相同的列时,我们可以按照这个列进行合并操作
    # 类似于数据库中的join操作
    
    In[]: df3 = DataFrame({'code':[600276, 600519], 'name':['hengrui', 'maotai'], 'bought_price': [0.00, 649.00]})
    
    In[]: df3
    Out[]: 
       bought_price    code     name
    0           0.0  600276  hengrui
    1         649.0  600519   maotai
    
    In[]: df3 = df3.rename(columns = {'bought_price':'in
         ...: _price'})
    Out[]:
       in_price    code     name
    0       0.0  600276  hengrui
    1     649.0  600519   maotai
    # 重命名单个或多个列索引
    
    In[]: df4 = DataFrame({'code': [600276, 600519], 'volume': [100, 100], 'in_date': ['2019-03-18', '2018-02-13']})
    
    In[]: df4
    Out[]: 
         code     in_date  volume
    0  600276  2019-03-18     100
    1  600519  2018-02-13     100
    
    In[]: pd.merge(df3, df4)
    Out[]: 
       in_price    code     name     in_date  volume
    0       0.0  600276  hengrui  2019-03-18     100
    1     649.0  600519   maotai  2018-02-13     100
    

    自我理解:

    • pd.concat([])用于合并行:当行内容不同时,列名相同
    • pd.merge()用于合并列:当列内容不同时,行名相同

    上面的代码中我们通过字典创建了两个数据集,可以看到当通过字段创建DataFrame数据集时,键名key变成了列名column name。
    df3和df4有共同的列course,当进行merge操作的时候Pandas会自动将这列进行合并。
    合并数据集时,有很多参数可以选择,比如选择在根据哪一列进行合并、合并的方式等,可以用help(pd.merge)查看完整的帮助文档。



    在Pandas中,也支持类似于数据库查询语句GROUP BY的功能,也就是按照某列进行分组,然后再分组上进行一些计算操作:

    In[]: df  = DataFrame({'user_id': ['Jack', 'Sam', 'Jack'], 'course': ['Math', 'Sci', 'Eng'], 'minutes': [9, 36, 45]})
    
    In[]: df
    Out[]: 
      course  minutes user_id
    0   Math        9    Jack
    1    Sci       36     Sam
    2    Eng       45    Jack
    
    # 方法一:筛选出所有user_id为'Jack'的行,然后进行求和统计:
    In[]: df[df['user_id'] == 'Jack']
    Out[]: 
      course  minutes user_id
    0   Math        9    Jack
    2    Eng       45    Jack
    
    In[]: df[df['user_id'] == 'Jack']['minutes']
    Out[]: 
    0     9
    2    45
    Name: minutes, dtype: int64
    
    In[]: df[df['user_id'] == 'Jack']['minutes'].sum()
    Out[]: 54
    # 可以看出我们可以先通过df[df['user_id'] =='Jack']布尔索引筛选出所有的相关行,然后通过结合列筛选功能过滤其他列,只剩下时间统计列(minutes所在列为学习时间列),最后通过求和运算统计出了学习时间。
    
    # 方法二:类似于数据库的GROUP BY功能进行计算:
    In[]: df[['user_id', 'minutes']]
    Out[]: 
      user_id  minutes
    0    Jack        9
    1     Sam       36
    2    Jack       45
    
    In[]: df[['user_id', 'minutes']].groupby('user_id').sum()
    Out[]: 
             minutes
    user_id
    Jack          54
    Sam           36
    # 可以看到,我们先过滤列,只剩下了user_id和minutes列,然后通过groupby方法在user_id列上进行分组并求和,相对于前一种方式,分组求和更灵活一些。
    

    自我理解分解:

    • 进行逻辑比较运算(Numpy和Pandas都可以),比如我们想知道一个多维数组中哪些值大于某一个指定值

    通过一个元素查询行数据

    # 1.
    In[]: df_bool = df['user_id'] == 'Jack'
    # 计算'user_id'列是否等于'Jack', 用df_bool显示
    In[]: df_bool
    Out[]: 
    0     True
    1    False
    2     True
    Name: user_id, dtype: bool
    
    In []: df[df_bool]
    Out[]:
      course  minutes user_id
    0   Math        9    Jack
    2    Eng       45    Jack
    # 将a_bool放在df中比较,将只显示a_bool中为'True'的'user_id列'所在的行内容。
    # 等同于df[df[...]]
    
    # 2.
    In[]: df[df['user_id'] == 'Jack']['minutes']
    Out[]: 
    0     9
    2    45
    Name: minutes, dtype: int64
    
    In[]: df[df['user_id'] == 'Jack'].minutes
    Out[]: 
    0     9
    2    45
    Name: minutes, dtype: int64
    # ['minutes']和.minutes的输出结果相同,都是对DataFrame的‘列选择’操作
    
    # 3. 上面筛选出来的是‘Name: minutes, dtype: int64’,所以.sum()是对minutes的元素值进行求和
    In[]: df[df['user_id'] == 'Jack']['minutes'].sum()
    Out[]: 54
    

    时间序列处理

    根据数据集中的时间戳进行运算,
    在Python中,时间处理方面的相关功能主要集中在datetime包中,主要有三种对象:

    • datetime.datetime:代表时间对象;
    • datetime.date:代表某一天;
    • datetime.timedelta:代表两个datetime.datetime对象之间的时间差。
    # datetime.datetime和datetime.timedelta的用法
    In[]: from date time import datetime, timedelta
    
    In[]: d1 = datetime(2017, 8, 1)
    Out[]: datetime.datetime(2017, 8, 1, 0, 0)
    
    In[]: delta = timedelta(days=10)
    
    In[]: d1 + delta
    Out[]: datetime.datetime(2017, 8, 11, 0, 0)
    
    In[]: dates = [datetime(2018, 1, 1), datetime(2018, 1, 2), datetime(2018, 1, 3), datetime(2018, 1, 4)]
    Out[]: 
    [datetime.datetime(2018, 1, 1, 0, 0),
     datetime.datetime(2018, 1, 2, 0, 0),
     datetime.datetime(2018, 1, 3, 0, 0),
     datetime.datetime(2018, 1, 4, 0, 0)]
    
    In[]: ts = Series(np.random.randn(4), index = dates)
    Out[]: 
    2018-01-01    0.241635
    2018-01-02    0.121023
    2018-01-03   -1.992435
    2018-01-04   -0.457257
    dtype: float64
    
    In[]: ts.index
    Out[]: DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04'], dtype='datetime64[ns]', freq=None)
    
    In[]: ts.index[0]
    Out[]: Timestamp('2018-01-01 00:00:00')
    
    # 通过datetime时间类型生成了一堆时间,然后基于此创建了一个时间序列ts, 可以看到ts的索引类型为DatetimeIndex类型。
    生成ts以后我们就有多种方法选择元素了,只需要传入一个能被Pandas识别的日期字符串就可以了,如下:
    
    In []: ts
    Out[]:
    2018-01-01    0.241635
    2018-01-02    0.121023
    2018-01-03   -1.992435
    2018-01-04   -0.457257
    dtype: float64
    
    In []: ts.index[0]
    Out[]: Timestamp('2018-01-01 00:00:00')
    
    In []: ts[ts.index[0]]
    Out[]: 0.2416345185713773
    
    In [311]: ts['2018-01-01']
    Out[311]: 0.2416345185713773
    
    In [312]: ts['2018/01/01']
    Out[312]: 0.2416345185713773
    
    In [313]: ts['1/1/2018']
    Out[313]: 0.2416345185713773
    
    In[]: ts[datetime(2018, 1, 1)]
    Out[315]: 0.2416345185713773
    # ts[ts.index[0]] , ts['2018-01-01'], ['2018-01-01'], ts['1/1/2018'], ts['1/1/2018'] 都可以选择同一个元素
    

    生成日期范围:

    在Pandas中生成日期范围主要通过pandas.date_range函数完成,该函数主要有以下几个参数:

    • start:指定了日期范围的起始时间;
    • end:指定了日期范围的结束时间;
    • periods:指定了间隔范围,如果只是指定了start和end日期中的其中一个,则需要改参数;
    • freq:指定了日期频率,比如D代表每天,H代表每小时,M代表月,这些频率字符前也可以指定一个整数,代表具体多少天。。。,比如5D代表5天。还有一些其他的频率字符串,比如MS代表每月第一天,BM代表每月最后一个工作日,或者是频率组合字符串,比如1h30min代表1小时30分钟。
      如下:
    In[]: pd.date_range('2018-1-1', '2019', freq = 'M')
    Out[]: 
    DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30',
                   '2018-05-31', '2018-06-30', '2018-07-31', '2018-08-31',
                   '2018-09-30', '2018-10-31', '2018-11-30', '2018-12-31'],
                  dtype='datetime64[ns]', freq='M')
    
    In[]: pd.date_range('2018-01-01', '2019', freq = 'BM')
    Out[]: 
    DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-30', '2018-04-30',
                   '2018-05-31', '2018-06-29', '2018-07-31', '2018-08-31',
                   '2018-09-28', '2018-10-31', '2018-11-30', '2018-12-31'],
                  dtype='datetime64[ns]', freq='BM')
    
    In[]: pd.date_range('2018-1-1', '2019', freq = 'MS')
    Out[]: 
    DatetimeIndex(['2018-01-01', '2018-02-01', '2018-03-01', '2018-04-01',
                   '2018-05-01', '2018-06-01', '2018-07-01', '2018-08-01',
                   '2018-09-01', '2018-10-01', '2018-11-01', '2018-12-01',
                   '2019-01-01'],
                  dtype='datetime64[ns]', freq='MS')
    # 更多date_range()方法的使用请看Pandas datetime学习笔记
    

    有的时候时间序列是按每小时显示统计的,但是我们想将统计频率转换成按天来统计,这个时候可以使用时间序列的resample方法,该方法非常强大,不仅仅支持高频率的数据聚合到低频率(降采样),也支持低频率转化到高频率统计(升采样):

    In[]: dates = pd.date_range('2018-1-1', '2018-1-2 23:00:00', freq = 'H')
    
    In[]: len(dates)
    Out[]: 48
    
    In[]: ts = Series(np.arange(len(dates)), index = dates)
    
    In[]: ts.size
    Out[]: 48
    
    In[]: ts.head(5)
    Out[]:
    2018-01-01 00:00:00    0
    2018-01-01 01:00:00    1
    2018-01-01 02:00:00    2
    2018-01-01 03:00:00    3
    2018-01-01 04:00:00    4
    Freq: H, dtype: int64
    
    
    In[]: ts.tail(5)
    Out[]: 
    2018-01-02 19:00:00    43
    2018-01-02 20:00:00    44
    2018-01-02 21:00:00    45
    2018-01-02 22:00:00    46
    2018-01-02 23:00:00    47
    Freq: H, dtype: int64
    

    以上代码中,我们创建了以每小时为频率的时间序列.

    如果我们将以上数据转换为按每天的数据统计:

    In[]: ts.resample('D').sum()
    Out[]: 
    2018-01-01    276
    2018-01-02    852
    Freq: D, dtype: int64
    # 先使用resample('D')方法指定了按天统计,接着使用sum方法求和了按天的所有数据(0-23相加,24-47相加)
    
    # 当把底频率的数据转换成高频率的数据时,默认情况下Pandas会引入NaN值,因为没办法从低频率的数据计算出高频率的数据,但可以通过fill_method参数指定插入值的方式:
    In[]: ts.resample('D').mean().resample('H').mean()
    Out[]: 
    2018-01-01 00:00:00    11.5
    2018-01-01 01:00:00     NaN
    2018-01-01 02:00:00     NaN
    2018-01-01 03:00:00     NaN
    2018-01-01 04:00:00     NaN
    2018-01-01 05:00:00     NaN
    2018-01-01 06:00:00     NaN
    2018-01-01 07:00:00     NaN
    2018-01-01 08:00:00     NaN
    2018-01-01 09:00:00     NaN
    2018-01-01 10:00:00     NaN
    2018-01-01 11:00:00     NaN
    2018-01-01 12:00:00     NaN
    2018-01-01 13:00:00     NaN
    2018-01-01 14:00:00     NaN
    2018-01-01 15:00:00     NaN
    2018-01-01 16:00:00     NaN
    2018-01-01 17:00:00     NaN
    2018-01-01 18:00:00     NaN
    2018-01-01 19:00:00     NaN
    2018-01-01 20:00:00     NaN
    2018-01-01 21:00:00     NaN
    2018-01-01 22:00:00     NaN
    2018-01-01 23:00:00     NaN
    2018-01-02 00:00:00    35.5
    Freq: H, dtype: float64
    
    In[]: ts.resample('D').mean().resample('H').ffill()
    # .fill()代表用前面的值替代NaN值
    Out[]: 
    2018-01-01 00:00:00    11.5
    2018-01-01 01:00:00    11.5
    2018-01-01 02:00:00    11.5
    2018-01-01 03:00:00    11.5
    2018-01-01 04:00:00    11.5
    2018-01-01 05:00:00    11.5
    2018-01-01 06:00:00    11.5
    2018-01-01 07:00:00    11.5
    2018-01-01 08:00:00    11.5
    2018-01-01 09:00:00    11.5
    2018-01-01 10:00:00    11.5
    2018-01-01 11:00:00    11.5
    2018-01-01 12:00:00    11.5
    2018-01-01 13:00:00    11.5
    2018-01-01 14:00:00    11.5
    2018-01-01 15:00:00    11.5
    2018-01-01 16:00:00    11.5
    2018-01-01 17:00:00    11.5
    2018-01-01 18:00:00    11.5
    2018-01-01 19:00:00    11.5
    2018-01-01 20:00:00    11.5
    2018-01-01 21:00:00    11.5
    2018-01-01 22:00:00    11.5
    2018-01-01 23:00:00    11.5
    2018-01-02 00:00:00    35.5
    Freq: H, dtype: float64
    
    

    相关文章

      网友评论

        本文标题:Python Pandas学习笔记。 vol4. 2019031

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