2016-10-04 95 views
2

这个问题与我先前提出的一个问题有些相关(Remapping `numpy.array` with missing values),我在时间序列中缺少数据,而有人建议“使用熊猫!。所以在这里我去...熊猫时间系列与缺失数据/​​记录的比较

我正在处理大型数据集,基本上包括来自不同观察点的时间序列,我希望统计比较网站。这些数据集相当混乱;大量缺失数据(例如用-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表示缺失值。我想比较来自不同地点(列id)的数据(列T,Td,cc),但如前所述,只有在任何两个或所有id都有我感兴趣的变量的数据(完全忽略是否其他列中的数据丢失)。

所以在这个例子中,如果所有的网站需要有数据,对比T只会导致从2001-01-01, 00:0003:00数据进行比较,因为在其他时间,无论是id=2id=3缺少T,并且最后一次纪录id=3在其他id中完全不存在。

我一直在玩这个好几个小时了,但说实话,我真的不知道从哪里开始。是否可以使用上面列出的尺寸n_sites x n_valid_values(本例为3x2)提取numpy.array,然后我可以使用它进行进一步分析?

编辑作为一个局部,但实际上(真的)丑陋的解决方案,这样的事情似乎工作:

# 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有更优雅的方法。

+0

为什么这些'2,2001-01-01,00:00,2.0,-99,-99'-99都可以吗? – Boud

+0

在这种情况下,我只关心'T'列是否有数据,忽略其他数据。 – Bart

回答

0

一种方法(在此基础上:https://stackoverflow.com/a/34985243/3581217答案),这似乎工作是创建一个Dataframe,其中来自不同网站的意见有不同的列,那么dropna()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'])结果:

In [234]: df 
Out[234]: 
         T1 T2 T3 id 
date_time        
2001-01-01 00:00:00 1.0 2.0 3.0 3 
2001-01-01 02:00:00 1.2 2.2 NaN 3 
2001-01-01 03:00:00 1.3 2.3 3.3 3 

这是要走的路?仍觉得有点不熊猫?