I was working on new function with Pandas DataFrame. It's meant to sort values by column name but exclude specific rows from sorting and return sorted dataframe with that has rows with preserved positions.
E.g. I have a DataFrame
Name marks
rank1 Tom 10
rank2 Jack 30
rank3 nick 50
rank4 juli 5
So I created a function (not finalized, but the idea)
def sort_df_values(df, column_names, ascending=False, fixed_categories=None):
if fixed_categories is not None and fixed_categories:
original_positions = {name: position for position, name in enumerate(df.index.values) if name in fixed_categories}
original_positions = dict(sorted(original_positions.items(), key=operator.itemgetter(1), reverse=True))
excluded = df.loc[fixed_categories]
included = [name for name in list(df.index) if name not in fixed_categories]
new_df = df.loc[included].sort_values(column_names, ascending=ascending)
result = pd.concat([new_df, excluded])
new_index_values = list(result.index.values)
while original_positions:
val, old_position = original_positions.popitem()
print(val, old_position)
for current_position, name in enumerate(new_index_values):
if name == val:
new_index_values.insert(old_position, new_index_values.pop(current_position))
break
result = result.reindex(new_index_values)
else:
result = df.sort_values(column_names, ascending=ascending)
return result
And then I call it like this:
sort_df_values(df, ['marks'], fixed_categories=['rank3'])
The result is correct, I sort all data, but I preserve the excluded rows positions:
Name marks
rank2 Jack 30
rank1 Tom 10
rank3 nick 50
rank4 juli 5
Is there any better option on how to do this? Maybe there is already some feature in pandas that could help me out on this one?
DataFrame example:
{'Name': {'rank1': 'Tom', 'rank2': 'Jack', 'rank3': 'nick', 'rank4': 'juli'},
'marks': {'rank1': 10, 'rank2': 30, 'rank3': 50, 'rank4': 5}}