Python pandas:Fast way to create a unique identifier for groups
<p>I have data that looks something like this</p>

<pre><code>df
Out[10]: 
  ID1 ID2  Price       Date
0  11  21  10.99  3/15/2016
1  11  22  11.99  3/15/2016
2  12  23      5  3/15/2016
3  11  21  10.99  3/16/2016
4  11  22  12.99  3/16/2016
5  11  21  10.99  3/17/2016
6  11  22  11.99  3/17/2016
</code></pre>

<p>The goal is to get a unique ID for each group of ID1 with particular prices for each of its ID2's, like so:</p>

<pre><code>    # Desired Result
df
Out[14]: 
  ID1 ID2  Price       Date  UID
0  11  21  10.99  3/15/2016    1
1  11  22  11.99  3/15/2016    1
2  12  23      5  3/15/2016    7
3  11  21  10.99  3/16/2016    5
4  11  22  12.99  3/16/2016    5
5  11  21  10.99  3/17/2016    1
6  11  22  11.99  3/17/2016    1
</code></pre>

<p>Speed is an issue because of the size of the data. The best way I can come up with is below, but it is still a fair amount slower than is desirable. If anyone has a way that they think should be naturally faster I'd love to hear it. Or perhaps there is an easy way to do the within group operations in parallel to speed things up? </p>

<p>My method basically concatenates ID's and prices (after padding with zeros to ensure same lengths) and then takes ranks to simplify the final ID. The bottleneck is the within group concatenation done with .transform(np.sum).</p>

<pre><code># concatenate ID2 and Price
df['ID23'] = df['ID2'] + df['Price']

df
Out[12]: 
  ID1 ID2  Price       Date     ID23
0  11  21  10.99  3/15/2016  2110.99
1  11  22  11.99  3/15/2016  2211.99
2  12  23      5  3/15/2016      235
3  11  21  10.99  3/16/2016  2110.99
4  11  22  12.99  3/16/2016  2212.99
5  11  21  10.99  3/17/2016  2110.99
6  11  22  11.99  3/17/2016  2211.99


# groupby ID1 and Date and then concatenate the ID23's
grouped = df.groupby(['ID1','Date'])
df['summed'] = grouped['ID23'].transform(np.sum)

df
Out[16]: 
  ID1 ID2    Price       Date      ID23            summed                UID
0   6   3  0010.99  3/15/2016  30010.99  30010.9960011.99  630010.9960011.99
1   6   6  0011.99  3/15/2016  60011.99  30010.9960011.99  630010.9960011.99
2   7   7  0000005  3/15/2016  70000005          70000005          770000005
3   6   3  0010.99  3/16/2016  30010.99  30010.9960012.99  630010.9960012.99
4   6   6  0012.99  3/16/2016  60012.99  30010.9960012.99  630010.9960012.99
5   6   3  0010.99  3/17/2016  30010.99  30010.9960011.99  630010.9960011.99
6   6   6  0011.99  3/17/2016  60011.99  30010.9960011.99  630010.9960011.99

# Concatenate ID1 on the front and take rank to get simpler ID's    
df['UID'] = df['ID1'] + df['summed'] 
df['UID'] = df['UID'].rank(method = 'min')

# Drop unnecessary columns
df.drop(['ID23','summed'], axis=1, inplace=True)
</code></pre>

<p>UPDATE:</p>

<p>To clarify, consider the original data grouped as follows:</p>

<pre><code>grouped = df.groupby(['ID1','Date'])
    for name, group in grouped:
    print group

  ID1 ID2  Price       Date
0  11  21  10.99  3/15/2016
1  11  22  11.99  3/15/2016

  ID1 ID2  Price       Date
3  11  21  10.99  3/16/2016
4  11  22  12.99  3/16/2016

  ID1 ID2  Price       Date
5  11  21  10.99  3/17/2016
6  11  22  11.99  3/17/2016

  ID1 ID2 Price       Date
2  12  23     5  3/15/2016
</code></pre>

<p>UID's should be at the group level and match if everything about that group is identical ignoring the date. So in this case the first and third printed groups are the same, meaning that rows 0,1,5, and 6 should all get the same UID. Rows 3 and 4 belong to a different group because a price changed and therefore need a different UID. Row 2 is also a different group.</p>

<p>A slightly different way of looking at this problem is that I want to group as I have here, drop the date column (which was important for initially forming the groups) and then aggregate across groups which are equal once I have removed the dates.</p>