Python: creating a group column in a Pandas dataframe based on an integer range of values
<p>For each range <code>[0, 150]</code> in the <code>diff</code> column, I want to create a group column that increases by 1 each time the range resets. When <code>diff</code> is negative, the range resets.</p>

<pre><code>import pandas as pd
df = pd.DataFrame({'year': [2016, 2016, 2016, 2016, 2016, 2016, 2016],
                   'month' : [1, 1, 2, 3, 3, 3, 3],
                   'day': [23, 25, 1, 1, 7, 20, 30]})
df = pd.to_datetime(df)
df = pd.concat([df, pd.Series(data=[15, 35, 80, 5, 20, 45, 90])], axis=1)
df.columns = ['date', 'percentworn']
col_shift = ['percentworn']
df_shift = df.shift(1).loc[:, col_shift]
df_combined = df.join(df_shift, how='inner', rsuffix='_2')
df_combined.fillna(value=0,inplace=True)
df_combined['diff'] = df_combined['percentworn'] - df_combined['percentworn_2']
</code></pre>

<p><a href="http://i.stack.imgur.com/YjiQf.png" rel="nofollow"><img src="http://i.stack.imgur.com/YjiQf.png" alt="enter image description here"></a></p>

<p>The <code>grp</code> columns should have <code>0, 0, 0, 1, 1, 1, 1</code>. The code I tried was</p>

<pre><code>def grping(df):
    df_ = df.copy(deep=True)
    i = 0
    if df_['diff'] &gt;= 0:
        df_['grp'] = i
    else:
        i += 1
        df_['grp'] = i
    return df_
df_combined.apply(grping,axis=1) 
</code></pre>

<p>I need to <code>i += 1</code> persist after incrementing. How can I achieve this? Or is there a better way get the desired results?</p>

<p><a href="http://i.stack.imgur.com/9PKgI.png" rel="nofollow"><img src="http://i.stack.imgur.com/9PKgI.png" alt="enter image description here"></a></p>

<p>IIUC you can test whether the <code>'diff'</code> column is negative which produces a boolean array, then cast this to <code>int</code> and the call <code>cumsum</code>:</p>

<pre><code>In [313]:
df_combined['group'] = (df_combined['diff'] &lt; 0).astype(int).cumsum()
df_combined

Out[313]:
        date  percentworn  percentworn_2  diff  group
0 2016-01-23           15            0.0  15.0      0
1 2016-01-25           35           15.0  20.0      0
2 2016-02-01           80           35.0  45.0      0
3 2016-03-01            5           80.0 -75.0      1
4 2016-03-07           20            5.0  15.0      1
5 2016-03-20           45           20.0  25.0      1
6 2016-03-30           90           45.0  45.0      1
</code></pre>

<p>breaking the above down:</p>

<pre><code>In [314]:
df_combined['diff'] &lt; 0

Out[314]:
0    False
1    False
2    False
3     True
4    False
5    False
6    False
Name: diff, dtype: bool

In [316]:
(df_combined['diff'] &lt; 0).astype(int)

Out[316]:
0    0
1    0
2    0
3    1
4    0
5    0
6    0
Name: diff, dtype: int32
</code></pre>

python pandas