替代耗时的循环,用于全年累计(YTM–年环比)测量

  • 本文关键字:YTM 测量 循环 用于 sql pandas
  • 更新时间 :
  • 英文 :


我有一个问题一直在努力解决,现在我向您求助。我有两个数据库DB1DB2,以及我需要处理的数据的几个标准:

ExcludeDates=['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04','2019-04-19','2019-04-22','2019-05-01','2019-05-31','2019-06-07','2019-12-21','2019-12-22','2019-12-23','2019-12-24','2019-12-25','2019-12-26','2019-12-27','2019-12-28','2019-12-29','2019-12-30','2019-12-31']
Region = ['Region1','Region2', 'Region3', 'Region4', 'Region5', 'Region6']
months        = [1,2,3,4,5,6,7,8,9,10,11,12]

现在,我想用从DB1DB2检索到的特征对一个月内累积的每个Region进行大量计算,即JanJan-FebJan-Mar、…、Jan-Dec

我最初的想法是循环一年中的所有子集(上面显示为JanJan-FebJan-Mar、…、Jan-Dec(和嵌套在另一个循环中的循环中的区域:

Measure_ytm = []
for RegionName in Region:
for month in months:
year           = 2019
month          = month
System  = 'System1'
SystemV = 'System1V'
Query1 = """
select 
a.feature1
,a.feature2
,a.feature3
from DB1 as a
inner join DateTable1 as  cd on a.Date = cd.Date
inner join TimeTable as ct on A.Time = ct.Time

where 1=1 
and a.feature6 = @System
and cd. Year = @year
and (cd.MonthOfYear between 1 and @month)
"""
new_query = query1.replace('@feature6', ''' + System + ''').replace('@year', 
str(year)).replace('@month', str(month))
with pymssql.connect(server=server, user=user, password=password, database='BD1') as conn:
with conn.cursor(as_dict=True) as cursor:
cursor.execute(new_query)        
all_rows = cursor.fetchall()
df1 = pd.DataFrame(all_rows)
query2 = """
select
b.Year as [Year]
,b.mon as [Month]
, a.TId as [SystemV] 
,a.Name as [RegionName]
, v.Namn as [Description]
, m.Namn as [Type]
,b.Value
from DB2 as b
inner join MTable as m on b.MId=m.Id
inner join VTable as v on b.VId=v.Id
inner join AMTable as  a on b.AMId=a.Id
where 1=1
and f.Year=@year
and (f.Mon between 1 and @month)
and b.TId=@SystemV
"""
query2 = query2.replace('@SystemV', ''' + SystemV + ''').replace('@year', 
str(year)).replace('@month', str(month))
with pymssql.connect(server=server, user=user, password=password, database='DB2') as conn:
with conn.cursor(as_dict=True) as cursor:
cursor.execute(new_query) 
all_rows = cursor.fetchall()
df2 = pd.DataFrame(all_rows)

### Follows a list of operations on the retrived dataframe df1 and df2 which result
x  = <an array containing the YTM accumulated value, each value in the aray belonging to one Region>
Measure_ytm.append(x)

现在,如前所述,如果将所有月份都考虑在内(即,如果执行所有JanJan-FebJan-Mar、…、Jan-Dec(,则这项工作很好,但需要两个10小时。所有地区的第一次通行证仅为1月,所有地区的第二次通行证为1月和2月,依此类推。在某些情况下,因为我甚至可能将Region更改为更长的regions列表,所以我的电脑内存不足。我试着用另一种方式改变

months        = [1,2,3,4,5,6,7,8,9,10,11,12]

months        = [[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5],[1,2,3,4,5,6],…..,[1,2,3,4,5,6,7,8,9,10,11,12]]

(cd.MonthOfYear between 1 and @month)替换为(cd.MonthOfYear in List),其中List是每次通过时的列表(即,如果循环在通过5时,则为[1,2,3,4,5],但这并不能解决问题。现在,请注意:如果每次只花1个月的时间,那么需要在代码的panda部分中完成的许多操作都可以在SQL查询部分中完成。对于所有地区和月份,整个代码运行需要20秒(DB1.中大约有2500万行

因此,我的问题是:有更有效的方法吗?我的猜测是避免循环,但怎么做呢?我的经验是,在这种情况下应该避免循环,这证明了我是对的。很明显,CCD_ 22的使用是问题的根源。

感谢来自一群聪明人的帮助!

添加了我的评论作为答案-请勾选它是否对您有所帮助。感谢

看起来每个数据集都只是每个月数据的并集。例如,Jan Feb是Jan和Feb的数据并集。如果是这样的话,为什么不全年运行一次查询,Jan Dec,并将月份和地区作为列包含在select语句中呢。然后,您可以在代码中从该数据集中选择您想要的记录,即只在处理df1/df2时在代码中放置循环,而不是围绕SQL?

最新更新