I can think of 2 ways of doing this:
- Apply
df.query
to match each row, then collect the index of each result - Set the column
domain
to be the index, and then reorder based on the index (but this would lose the index which I want, so may be trickier)
However I'm not sure these are good solutions (I may be missing something obvious)
Here's an example set up:
domain_vals = list("ABCDEF")df_domain_vals = list("DECAFB")df_num_vals = [0,5,10,15,20,25]df = pd.DataFrame.from_dict({"domain": df_domain_vals, "num": df_num_vals})
This gives df
:
domain num0 D 01 E 52 C 103 A 154 F 205 B 25
1: Use df.query
on each row
So I want to reorder the rows according using the values in order of domain_vals
for the column domain
.
A possible way to do this is to repeatedly use df.query
but this seems like an un-Pythonic (un-panda-ese?) solution:
>>> pd.concat([df.query(f"domain == '{d}'") for d in domain_vals]) domain num3 A 155 B 252 C 100 D 01 E 54 F 20
2: Setting the column domain
as the index
reorder = df.domain.apply(lambda x: domain_vals.index(x))df_reorder = df.set_index(reorder)df_reorder.sort_index(inplace=True)df_reorder.index.name = None
Again this gives
>>> df_reorder domain num0 A 151 B 252 C 103 D 04 E 55 F 20
Can anyone suggest something better (in the sense of "less of a hack"). I understand that my solution works, I just don't think that calling pandas.concat
along with a list comprehension is the right approach here.
Having said that, it's shorter than the 2nd option, so I presume there must be some equally simple way I can do this with pandas
methods I've overlooked?