pandas逐个对象(时间序列)中的多变量派生

时间:2017-09-12 08:09:06

标签: python pandas

根据规范,我有一个 DataFrame 。下面。实际大小约为1亿行,大约150列:

df = pd.DataFrame({'id' : [1,1,1,1,3,3,3,3]
               ,'time_ref' : ['20150401','20150401','20150401','20150401','20150401','20150401','20150401','20150401']
               ,'time' : ['20150101', '20150201','20150301','20150401', '20150101',' 20150201','20150301','20150401']
               ,'disc' : [3,3,1,1,2,4,5,7]}
              ,columns =['id', 'time_ref','time', 'disc' ]
             ) 

for time in ['time_ref','time']:
    df[time] = pd.to_datetime(df[time]
                          ,format = '%Y%m%d'
                          ,errors = 'ignore')


df

我已经解决了这个问题,即出现在下面:

df2 = pd.DataFrame({'id' : [1,1,1,1,3,3,3,3]
               ,'time_ref' : ['20150401','20150401','20150401','20150401','20150401','20150401','20150401','20150401']
               ,'time' : ['20150101', '20150201','20150301','20150401', '20150101',' 20150201','20150301','20150401']
               ,'disc' : [3,3,1,1,2,4,5,7]
               ,'disc_agg_diff' : [-2,-2,-2,-2,2,2,2,2]
               ,'disc_agg_time_diff' : [2, 2,2 ,2,1,1,1,1]}
             ,columns =['id', 'time_ref','time', 'disc', 'disc_agg_diff','disc_agg_time_diff']
             )  

for time in ['time_ref','time']:
    df2[time] = pd.to_datetime(df2[time]
                          ,format = '%Y%m%d'
                          ,errors = 'ignore')


df2
  • disc_agg_diff看起来与变量disc中的第一次更改有区别,即(1)= -2时间点20150301为id` = 1。对于id 3,在时间点20150401处(7-2)= 5。

  • disc_agg_time_diff查看发生更改的时间段(月)。对于id 1,2个周期。对于id 3,1期间。

我从很多groupbys,left join和numpy.where获得结果,通过每个ID和他们的月度数据点。问题是代码现在很大,如果我添加更多具有相同派生的变量会变得更大并且有点过于混乱。

我的问题是:这个结果能否以干净有效的方式获得,代码老虎,其中推导完成(减法)可以是引号,添加列等。此外,速度是至关重要,因为数据量非常大。

非常感谢您提前和考虑!

/ Swepab

1 个答案:

答案 0 :(得分:0)

您可以使用transform。我发现了一篇相当不错的沼泽帖子,解释了它在pbpython.com

上的作用

这样的东西可以得到第一列

disc_agg_diff

def get_disc_agg_diff(disc_column):
    return disc_column.diff().replace(0, None).dropna().iloc[0]

根据您的数据,使用for循环可能会更有效.replace.dropnailoc

df.groupby('id')['disc'].transform(get_first_diff)

返回

0   -2
1   -2
2   -2
3   -2
4    2
5    2
6    2
7    2

disc_agg_time_diff

的工作方式与`get_first_diff

大致相同
def get_disc_agg_time_diff(disc_column):
    diff = disc_column.diff().reset_index(drop=True)
    diff_reduced = diff.replace(0, None).dropna()
    return diff_reduced.index[0]

在这里,替代方案是for循环,但这是有效的。