根据规范,我有一个 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
答案 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
,.dropna
和iloc
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循环,但这是有效的。