I've been building on some principles from Richard Fairhurst's Blog/blogs/richard_fairhurst/2014/11/08/turbo-charging-data-manipulation-with-python-cursors-and-dictionaries My goal is to map the average daily well volume for the past 90 days. I have a table of daily volumes for about 1,300 wells. There are several years worth of records in the table. I also have a Python dictionary. The keys in the dictionary are the unique identifier for each well represented in the table. The values in the dictionary start as empty lists. The following block of code populates the dictionary values with the daily volume values from the past 92 days for each well. The code works, but it takes approximately 40 seconds for each well. How can I modify the code to improve performance? Please see the code and comments below. Any suggestions would be greatly appreciated.
i <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN> <SPAN class="comment token"># This is a counter for testing purposes</SPAN>
table <SPAN class="operator token">=</SPAN> acDaily <SPAN class="comment token"># This is a SQL Server database table of daily water volumes. There are ~1300 wells represented in the table, each with daily records covering several years.</SPAN>
fields <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="string token">'PROPNUM'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'D_DATE'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'WATER'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="comment token"># PROPNUM is the unique identifier for each well in acDaily, D_DATE is the date of the daily volume, and WATER is the volume of produced water.</SPAN>
<SPAN class="keyword token">for</SPAN> prop <SPAN class="keyword token">in</SPAN> propNumDict<SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># Iterate through each item in propNumDict. propNumDict is a Python dictionary with keys that are the unique values in the acDaily PROPNUM field. The dictionary values start as empty lists.</SPAN>
i <SPAN class="operator token">+=</SPAN> <SPAN class="number token">1</SPAN>
<SPAN class="keyword token">print</SPAN> str<SPAN class="punctuation token">(</SPAN>i<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">" - "</SPAN> <SPAN class="operator token">+</SPAN> strftime<SPAN class="punctuation token">(</SPAN><SPAN class="string token">"%Y-%m-%d %H:%M:%S"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># This is used to time the duration of each iteration, which is currently ~40 seconds.</SPAN>
<SPAN class="keyword token">if</SPAN> i <SPAN class="operator token">></SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">break</SPAN>
<SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>table<SPAN class="punctuation token">,</SPAN> fields<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> cursor<SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># Use a search cursor to go through the records in acDaily and if the PROPNUM matches the key in propNumDict and the records are from the past 92 days, add the water volume value to the dictionary.</SPAN>
<SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> cursor<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">==</SPAN> prop <SPAN class="operator token">and</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">></SPAN> tMinus92<SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># tMinus92 is a variable defined as datetime.datetime.today() - timedelta(days = 92). It takes two days for the data to make it into this table.</SPAN>
propNumDict<SPAN class="punctuation token">[</SPAN>prop<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">print</SPAN> propNumDict
<SPAN class="keyword token">print</SPAN> strftime<SPAN class="punctuation token">(</SPAN><SPAN class="string token">"%Y-%m-%d %H:%M:%S"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>After the propNumDict dictionary is populated, I have another block of code that creates a new dictionary and populates it with the average values for each key in propNumDict. Here's what that looks like:
avgDailyDict <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">for</SPAN> key<SPAN class="punctuation token">,</SPAN> values <SPAN class="keyword token">in</SPAN> propNumDict<SPAN class="punctuation token">.</SPAN>iteritems<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> float<SPAN class="punctuation token">(</SPAN>len<SPAN class="punctuation token">(</SPAN>values<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">></SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">:</SPAN>
avgDailyDict<SPAN class="punctuation token">[</SPAN>key<SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> sum<SPAN class="punctuation token">(</SPAN>values<SPAN class="punctuation token">)</SPAN><SPAN class="operator token">/</SPAN>float<SPAN class="punctuation token">(</SPAN>len<SPAN class="punctuation token">(</SPAN>values<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">print</SPAN> avgDailyDict<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>arc gis python
dictionary
arcpy.da.searchcursor