This may not be wholly an ArcGIS problem but I always seem to get the best answers from this group!
I'm working with the new ESRI Tracker feature service and trying to summarize the json output a bit to generate reports. The specific task is to maintain a running total of seconds between successive point features using the "location_timestamp" column. I won't go into the query portion where we are acquiring the json from the feature service (it's all basic/simple stuff just querying the REST interface with urllib2.Request).
I'll put 2 versions (short & long version has all details, just read everything after the *****)
The short version -- grouping to sum an "elapsedSeconds" column:
grouped <SPAN class="operator token">=</SPAN> df<SPAN class="punctuation token">.</SPAN>groupby<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_day'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'PEP_land_name'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'PEP_land_rate'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'created_user'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'elapsedSeconds'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>sum<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>reset_index<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN></SPAN>
Revert this grouped dataframe back into json:
dfjson <SPAN class="operator token">=</SPAN> grouped<SPAN class="punctuation token">.</SPAN>to_json<SPAN class="punctuation token">(</SPAN>orient<SPAN class="operator token">=</SPAN><SPAN class="string token">'records'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN></SPAN>
This is where I end up with an "overflowerror maximum recursion level reached".
************
The long version with more detail about what I'm doing. To start, I'm just querying the REST of a hosted feature service (the ESRI tracker service):
tracksReq <SPAN class="operator token">=</SPAN> urllib2<SPAN class="punctuation token">.</SPAN>Request<SPAN class="punctuation token">(</SPAN>urlTrackerMain <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/query'</SPAN><SPAN class="punctuation token">,</SPAN> tracksParams<SPAN class="punctuation token">)</SPAN>
tracksResponse <SPAN class="operator token">=</SPAN> urllib2<SPAN class="punctuation token">.</SPAN>urlopen<SPAN class="punctuation token">(</SPAN>tracksReq<SPAN class="punctuation token">)</SPAN>
tracksResult <SPAN class="operator token">=</SPAN> json<SPAN class="punctuation token">.</SPAN>load<SPAN class="punctuation token">(</SPAN>tracksResponse<SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
And whammo, I have the json output of the tracker service. From here I add some columns to the json for various things:
<SPAN class="keyword token">if</SPAN> tracksResult <SPAN class="keyword token">is</SPAN> <SPAN class="operator token">not</SPAN> None<SPAN class="punctuation token">:</SPAN>
output <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">for</SPAN> jj <SPAN class="keyword token">in</SPAN> tracksResult<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'features'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">:</SPAN>
int_num <SPAN class="operator token">=</SPAN> int<SPAN class="punctuation token">(</SPAN>str<SPAN class="punctuation token">(</SPAN>json<SPAN class="punctuation token">.</SPAN>dumps<SPAN class="punctuation token">(</SPAN>jj<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'attributes'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_timestamp'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
utc <SPAN class="operator token">=</SPAN> time<SPAN class="punctuation token">.</SPAN>strftime<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'%Y-%m-%d %H:%M:%S'</SPAN><SPAN class="punctuation token">,</SPAN> time<SPAN class="punctuation token">.</SPAN>gmtime<SPAN class="punctuation token">(</SPAN>int_num<SPAN class="operator token">/</SPAN><SPAN class="number token">1000.0</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
convTimeStamp <SPAN class="operator token">=</SPAN> time<SPAN class="punctuation token">.</SPAN>strftime<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'%Y-%m-%d %H:%M:%S'</SPAN><SPAN class="punctuation token">,</SPAN> time<SPAN class="punctuation token">.</SPAN>gmtime<SPAN class="punctuation token">(</SPAN>int_num<SPAN class="operator token">/</SPAN><SPAN class="number token">1000.0</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
convDayStamp <SPAN class="operator token">=</SPAN> time<SPAN class="punctuation token">.</SPAN>strftime<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'%Y-%m-%d'</SPAN><SPAN class="punctuation token">,</SPAN> time<SPAN class="punctuation token">.</SPAN>gmtime<SPAN class="punctuation token">(</SPAN>int_num<SPAN class="operator token">/</SPAN><SPAN class="number token">1000.0</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
jj<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'attributes'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_timestamp_local'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> convTimeStamp
jj<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'attributes'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_day'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> convDayStamp
output<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>jj<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'attributes'</SPAN><SPAN class="punctuation token">]</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>So now I have a new output with some extra columns (converted those epoch datetime values to something meaningful). Now from here I am ready to do some grouping/summarizing using Pandas:
df <SPAN class="operator token">=</SPAN> pd<SPAN class="punctuation token">.</SPAN>DataFrame<SPAN class="punctuation token">.</SPAN>from_dict<SPAN class="punctuation token">(</SPAN>output<SPAN class="punctuation token">,</SPAN> orient<SPAN class="operator token">=</SPAN><SPAN class="string token">'columns'</SPAN><SPAN class="punctuation token">)</SPAN>
df<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_timestamp_local'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="operator token">=</SPAN> pd<SPAN class="punctuation token">.</SPAN>to_datetime<SPAN class="punctuation token">(</SPAN>df<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_timestamp_local'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN>
df <SPAN class="operator token">=</SPAN> df<SPAN class="punctuation token">.</SPAN>sort<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'location_timestamp_local'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Here's where I am creating that running total column in the dataframe:
<SPAN class="comment token">#determine duration in seconds between the previous row's datetime value. Do this for each day.</SPAN>
df<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'elapsedSeconds'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> df<SPAN class="punctuation token">.</SPAN>sort<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'location_timestamp_local'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>groupby<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_day'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'PEP_land_name'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_timestamp_local'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>diff<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="operator token">/</SPAN><SPAN class="number token">1000</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN></SPAN>
All is good and well. Now for some grouping to sum that "elapsedSeconds" value.
grouped <SPAN class="operator token">=</SPAN> df<SPAN class="punctuation token">.</SPAN>groupby<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'location_day'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'PEP_land_name'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'PEP_land_rate'</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">'created_user'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'elapsedSeconds'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>sum<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>reset_index<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN></SPAN>
And finally revert this grouped dataframe back into json:
dfjson <SPAN class="operator token">=</SPAN> grouped<SPAN class="punctuation token">.</SPAN>to_json<SPAN class="punctuation token">(</SPAN>orient<SPAN class="operator token">=</SPAN><SPAN class="string token">'records'</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="line-numbers-rows"><SPAN></SPAN></SPAN>
This is where I end up with an "overflowerror maximum recursion level reached". It doesn't seem to error when I run in pyScripter v2.6 x86 but it fails when I hook up this .py script to a Geoprocessing tool source. This is likely the issue (32-bit vs. 64?), I'm unsure and really just looking for workarounds if known.
Anyway -- thanks for looking and should be a fun one to figure out!
ArcGIS 10.4
Pandas 0.16.1