熊猫时间序列与缺失数据/​​记录的比较

时间:2016-10-04 14:02:34

标签: python pandas time-series

这个问题与我之前提出的一个问题(Remapping `numpy.array` with missing values)有些相关,我正在努力处理缺少数据的时间序列,有人建议“使用Pandas!”。所以我走了......

我正在处理大型数据集,基本上包括来自不同观察站点的时间序列,我想在统计上比较这些站点。这些数据集非常混乱;大量缺失数据(用例如-99表示),缺少时间记录(一个站可能有时间记录,另一个站没有),我只想包含/比较数据,其中(1)所有站点都有数据某个变量,或者(2)我想比较的两个站点有该变量的数据,忽略其他站点(不)是否有数据。

以这个最小的例子:

import pandas as pd
from io import StringIO

data = StringIO("""\
  1,  2001-01-01, 00:00, 1.0, 0.5, 1.0
  1,  2001-01-01, 01:00, 1.1, 0.6, 2.0
  1,  2001-01-01, 02:00, 1.2, 0.7, 3.0
  1,  2001-01-01, 03:00, 1.3, 0.8, 4.0

  2,  2001-01-01, 00:00, 2.0, -99, -99
  2,  2001-01-01, 01:00, -99, 1.6, 2.0
  2,  2001-01-01, 02:00, 2.2, 1.7, 3.0
  2,  2001-01-01, 03:00, 2.3, 1.8, 4.0

  3,  2001-01-01, 00:00, 3.0, 2.5, 1.0
  3,  2001-01-01, 01:00, 3.1, 2.6, -99
  3,  2001-01-01, 02:00, -99, -99, 3.0
  3,  2001-01-01, 03:00, 3.3, 2.8, 4.0
  3,  2001-01-01, 04:00, 3.4, 2.9, 5.0
""")

columns = ['id','date','time','T','Td','cc']
df = pd.read_table(data, header=None, names=columns, delimiter=',', na_values=-99, parse_dates=[['date','time']])

-99表示缺失值。我想比较来自不同网站(列T)的数据(列Tdccid),但如上所述,只有两个或全部{ {1}}有我感兴趣的变量的数据(完全忽略其他列中的数据是否缺失)。

因此,对于此示例,如果所有网站都需要包含数据,那么比较id只会比较来自T2001-01-01, 00:00的数据,因为在其他时间,03:00id=2 1}}或id=3缺少Tid=3的最后一次记录在其他id中完全不存在。

我已经玩了好几个小时了,但说实话,我真的不知道从哪里开始。是否可以使用上面列出的标准numpy.array提取n_sites x n_valid_values3x2(本例),我可以将其用于进一步分析?

编辑作为一个部分但真正(真正)丑陋的解决方案,这样的事情似乎有效:

# Loop over all indexes where T is nan:
for i in np.where(df['T'].isnull())[0]:
    # For each of them, set records with the same date_time to nan
    j = np.where(df['date_time'] == df['date_time'][i])[0]
    df['T'][j] = np.nan
# Drop all records where T is nan
df2 = df.dropna(subset=['T'])

# Group by the different stations:
g = df2.groupby('id')

# Get the arrays (could automate this based on the unique id's):
v1 = g.get_group(1)['T']
v2 = g.get_group(2)['T']
v3 = g.get_group(3)['T']

但是这仍然没有删除id=3date_time=2001-01-01, 04:00的记录,我想/希望Pandas有更优雅的方法。

1 个答案:

答案 0 :(得分:0)

一种似乎有效的方法(基于此:https://stackoverflow.com/a/34985243/3581217答案)可以创建Dataframe,其中来自不同网站的观察结果具有不同的列,然后是dropna() { {1}}设置为所有列或我想要比较的两个站点,这会删除缺少数据的所有行。

subset

结果import pandas as pd import numpy as np from io import StringIO data1 = StringIO("""\ 1, 2001-01-01, 00:00, 1.0 1, 2001-01-01, 01:00, 1.1 1, 2001-01-01, 02:00, 1.2 1, 2001-01-01, 03:00, 1.3 """) data2 = StringIO("""\ 2, 2001-01-01, 00:00, 2.0 2, 2001-01-01, 01:00, -99 2, 2001-01-01, 02:00, 2.2 2, 2001-01-01, 03:00, 2.3 """) data3 = StringIO("""\ 3, 2001-01-01, 00:00, 3.0 3, 2001-01-01, 01:00, 3.1 3, 2001-01-01, 02:00, -99 3, 2001-01-01, 03:00, 3.3 3, 2001-01-01, 04:00, 3.4 """) columns = ['id','date','time','T1'] df1 = pd.read_table(data1, header=None, names=columns, delimiter=',', na_values=-99, parse_dates=[['date','time']]) columns = ['id','date','time','T2'] df2 = pd.read_table(data2, header=None, names=columns, delimiter=',', na_values=-99, parse_dates=[['date','time']]) columns = ['id','date','time','T3'] df3 = pd.read_table(data3, header=None, names=columns, delimiter=',', na_values=-99, parse_dates=[['date','time']]) df = pd.concat([df1,df2,df3]).groupby('date_time').max() df = df.dropna(subset=['T1','T2','T3']) 看起来像:

Dataframe

如果我只想比较两个网站,在这种情况下忽略In [232]: df Out[232]: T1 T2 T3 id date_time 2001-01-01 00:00:00 1.0 2.0 3.0 3 2001-01-01 03:00:00 1.3 2.3 3.3 3 ,则T3会导致:

df.dropna(subset=['T1','T2'])

这是要走的路吗?还是觉得有点非Panda-ish ..?