Python Pandas学习笔记。 vol4. 20190317

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


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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341