使用熊猫和日期处理奇怪的绘图结果

时间:2019-06-13 08:38:24

标签: python pandas csv plot

当使用日期绘制带有熊猫的时间序列时,该图完全错误,因为沿x轴的日期也是如此。出于某种原因,即使没有在数据框中也针对日期绘制数据。

这用于绘制具有独立时钟和不同采样频率的多个传感器。我想在同一图中绘制所有传感器以进行比较。

我尝试按升序对数据框进行排序,并且将datetime列分配为数据框索引而没有任何效果。当根据时间戳绘制数据集时,每个传感器的绘制看起来都很好。

摘录自典型CSV文件:

    Timestamp Date Clock DC3 HR DC4
    13 18.02.2019 08:24:00  19,12   61  3
    14 18.02.2019 08:26:00  19,12   38  0
    15 18.02.2019 08:28:00  19,12   52  0
    16 18.02.2019 08:30:00  19,12   230 2
    17 18.02.2019 08:32:00  19,12   32  3

以下代码为我带来了问题:

import pandas as pd
from scipy.signal import savgol_filter

columns = ['Timestamp', 'Date', 'Clock', 'DC3', 'HR', 'DC4']

data = pd.read_csv('Exampledata.DAT', 
               sep='\s|\t', 
               header=19, 
               names=columns, 
               parse_dates=[['Date', 'Clock']], 
               engine='python')

data['HR'] = savgol_filter(data['HR'], 201, 3) #Smoothing

ax = data.plot(x='Date_Clock', y='HR', label='Test')

仅在x轴上带有日期的情况下,预期结果应如下所示:

Imgur

实际结果是: Imgur

可以在此处下载完整数据文件的示例: https://filesender.uninett.no/?s=download&token=ae8c71b5-2dcc-4fa9-977d-0fa315fedf45

该问题如何解决?

2 个答案:

答案 0 :(得分:1)

此问题的解决方法是,在加载文件时不使用parse_dates,而是创建如下的datetime向量:

import pandas as pd
from scipy.signal import savgol_filter

columns = ['Timestamp', 'Date', 'Clock', 'DC3', 'HR', 'DC4']

data = pd.read_csv('Exampledata.DAT', 
               sep='\s|\t', 
               header=19, 
               names=columns, 
               engine='python')

data['Timestamp'] = pd.to_datetime(data['Date'] + data['Clock'], 
format='%d.%m.%Y%H:%M:%S')

data['HR'] = savgol_filter(data['HR'], 201, 3) #Smoothing

ax = data.plot(x='Timestamp', y='HR', label='Test')

这将创建以下图:

Imgur

我想要哪个情节。

答案 1 :(得分:0)

您会得到一个奇怪的图,因为matplotlib每行绘制一个点。如果您想要一个更易于阅读的图表,可以使用resample()函数将您的条目分组为每天1个(或每周1个或每月1个,如果您愿意)。重采样时有两个主要选项,您可以选择取所有条目的总和,也可以取均值。我任意决定取平均值。

这是它的样子:

#Loading in the csv file
filename = 'data_test.xlsx'
df1 = pd.read_excel(filename, sep=',', index_col=False, header =None)
df1.columns =  ['to_delete', 'Timestamp', 'DC3', 'HR', 'DC4', 'DC5']
df1.drop(columns = 'to_delete', inplace = True)
df1['Timestamp'] = [datetime.strptime(x, '%d.%m.%Y %H:%M:%S') for x in df1['Timestamp']]

# We put the timestamp in the index since it's needed by the resample function
df1 = df1.set_index(["Timestamp"])
# We resample to have one row per day
df1 = df1.resample("1d").mean()

#We plot the graph
x = df1.plot(y='HR', label='Test')

以下是带有重采样的图形:

with_resample

要比较的是没有重采样的图形:

enter image description here