I come from a sql background and I use the following data processing step frequently: Partition the table of data by one or more fields For each partition, add a rownumber to each of its rows that ranks the row by one or more other fields, where the analyst specifies ascending or descending EX: df = pd.DataFrame({'key1' : ['a','a','a','b','a'], 'data1' : [1,2,2,3,3], 'data2' : [1,10,2,3,30]}) df d