我正在解析一个文件,该文件按时间顺序为多个时间序列加上时间戳,我想在python中解析,然后使用matplotlib为每组时间序列数据创建一个带有独立行的单线图。我正在解析的数据看起来像这样:
time label value
1.05 seriesA 3.925
1.09 seriesC 0.245
2.13 seriesB 12.32
2.73 seriesC 4.921
我已经将文件解析为包含系列标签上键入的(时间,值)元组的列表字典。我正在努力解决如何从这个到所有这些数据的单线图。我想在单个图上使用seriesA,seriesB,seriesC等的独立行。有什么指针吗?
编辑:根据要求,字典在下面。我很难找出存储这些数据的最佳方法,所以我使用的数据结构也可能是一个问题。下面的键是不同的时间序列标签,值是(时间,值)元组的列表。无论如何,这里是:
{'client1': [(861.991698574, 298189000.0), (862.000768158, 0.0)],
'client2': [(861.781502324, 0.0), (861.78903722, 153600000.0),
(862.281483262, 0.0), (862.289038158, 153600000.0)], 'client3':
[(862.004470762, 3295674368.0), (862.004563939, 3295674368.0),
(862.03981821, 799014912.0), (862.040403314, 1599078400.0),
(862.540269616, 3295674368.0), (862.55133097, 1599078400.0)]}
我喜欢这类问题的熊猫。
首先,将数据放在pandas
数据帧中:
import pandas as pd
data = {'client1': [(861.991698574, 298189000.0), (862.000768158, 0.0)],
'client2': [(861.781502324, 0.0), (861.78903722, 153600000.0),
(862.281483262, 0.0), (862.289038158, 153600000.0)], 'client3':
[(862.004470762, 3295674368.0), (862.004563939, 3295674368.0),
(862.03981821, 799014912.0), (862.040403314, 1599078400.0),
(862.540269616, 3295674368.0), (862.55133097, 1599078400.0)]}
time = []
label = []
value = []
for k, v in data.items():
for tup in v:
label.append(k)
time.append(tup[0])
value.append(tup[1])
df = pd.DataFrame({'time':time, 'label':label, 'value':value})
导致此数据帧:
>>> df
label time value
0 client1 861.991699 2.981890e+08
1 client1 862.000768 0.000000e+00
2 client2 861.781502 0.000000e+00
3 client2 861.789037 1.536000e+08
4 client2 862.281483 0.000000e+00
5 client2 862.289038 1.536000e+08
6 client3 862.004471 3.295674e+09
7 client3 862.004564 3.295674e+09
8 client3 862.039818 7.990149e+08
9 client3 862.040403 1.599078e+09
10 client3 862.540270 3.295674e+09
11 client3 862.551331 1.599078e+09
然后,你可以这样做:
by_label = df.groupby('label')
for name, group in by_label:
plt.plot(group['time'], group['value'], label=name)
plt.legend()
plt.show
关于如何将数据存储在字典中;有不同的方法可以解决这个问题,但如果我是你,并且能够轻松地使用pandas
使用您的数据,我会使用以下形式的字典:
data = {'label':['client1', 'client1', 'client2', ...],
'time':[time1, time2, time3, ...],
'value':[value1, value2, value3, ...]}
确保所有列表都以正确的方式排序(所有3个键的索引0是数据帧的第0行,索引1是第1行,等等......)。然后要导入大熊猫,你需要做的就是df = pd.DataFrame(data)
简短回答:
突出显示并按ctrl + c显示以下数据:
label time value
client1 861.991699 2.981890e+08
client1 862.000768 0.000000e+00
client2 861.781502 0.000000e+00
client2 861.789037 1.536000e+08
client2 862.281483 0.000000e+00
client2 862.289038 1.536000e+08
client3 862.004471 3.295674e+09
client3 862.004564 3.295674e+09
client3 862.039818 7.990149e+08
client3 862.040403 1.599078e+09
client3 862.540270 3.295674e+09
client3 862.551331 1.599078e+09
然后运行此代码段:
# imports
import pandas as pd
# read data from the clipboard
df = pd.read_clipboard(sep='\\s+')
# reshape the data to get values by time for each label
df = df.pivot(index='time', columns='label', values='value')
# Replace nans by forward filling existing values
df = df.fillna(method = 'ffill')
# You'll still have to handle the missing values in the beginning of the coloumns
df = df.fillna(method = 'bfill')
# A simple plot:
df.plot()
然后你会得到:
细节
这个问题中有一些令人困惑的因素。如果您所说的源数据是以下形式:
time label value
1.05 seriesA 3.925
1.09 seriesC 0.245
2.13 seriesB 12.32
2.73 seriesC 4.921
但是数据的真实内容是:
{'client1': [(861.991698574, 298189000.0), (862.000768158, 0.0)],
'client2': [(861.781502324, 0.0), (861.78903722, 153600000.0),
(862.281483262, 0.0), (862.289038158, 153600000.0)], 'client3':
[(862.004470762, 3295674368.0), (862.004563939, 3295674368.0),
(862.03981821, 799014912.0), (862.040403314, 1599078400.0),
(862.540269616, 3295674368.0), (862.55133097, 1599078400.0)]}
那么您的数据的真实内容和形式应该是:
label time value
client1 861.991699 2.981890e+08
client1 862.000768 0.000000e+00
client2 861.781502 0.000000e+00
client2 861.789037 1.536000e+08
client2 862.281483 0.000000e+00
client2 862.289038 1.536000e+08
client3 862.004471 3.295674e+09
client3 862.004564 3.295674e+09
client3 862.039818 7.990149e+08
client3 862.040403 1.599078e+09
client3 862.540270 3.295674e+09
client3 862.551331 1.599078e+09
在任何情况下,绝对没有理由利用字典来获取你的字典
[...]包含所有这些数据的单线图。我希望在一个情节中为系列,系列,系列等提供独立的线条。
我相信最有效的方法是来自Reshaping and Pivot Tables的pandas docs。从那里你可以使用df.plot()
直接绘制数据。
突出显示并按住ctrl + c上面的数据,你很高兴:
# imports
import pandas as pd
# read data from the clipboard
df = pd.read_clipboard(sep='\\s+')
# reshape the data to get values by time for each label
df = df.pivot(index='time', columns='label', values='value')
print(df)
这应该代表您所需的数据形式:
label client1 client2 client3
time
861.781502 NaN 0.0 NaN
861.789037 NaN 153600000.0 NaN
861.991699 298189000.0 NaN NaN
862.000768 0.0 NaN NaN
862.004471 NaN NaN 3.295674e+09
862.004564 NaN NaN 3.295674e+09
862.039818 NaN NaN 7.990149e+08
862.040403 NaN NaN 1.599078e+09
862.281483 NaN 0.0 NaN
862.289038 NaN 153600000.0 NaN
862.540270 NaN NaN 3.295674e+09
862.551331 NaN NaN 1.599078e+09
鉴于有些特殊的时间指数,仍有一些问题需要处理。为了使这些数据更友好,我们应该处理缺失的值。这可以在使用df.fillna
的pandas docs的下一个片段中轻松完成:
# Replace nans by forward filling existing values
df = df.fillna(method = 'ffill')
# You'll still have to handle the missing values
# in the beginning of the coloumns
df = df.fillna(method = 'bfill')
现在,您只需使用df.plot()
即可获得折线图:
编辑:
让我知道您的数据源是什么,以便为您提供有关如何读取和存储数据的一些提示。再说一次,熊猫很可能是最好的选择。