Quantcast
Channel: User Louis Maddox - Stack Overflow
Viewing all articles
Browse latest Browse all 51

Reorder rows of pandas DataFrame according to a known list of values

$
0
0

I can think of 2 ways of doing this:

  1. Apply df.query to match each row, then collect the index of each result
  2. 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?


Viewing all articles
Browse latest Browse all 51

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>