Search code examples
pythonpandasgroup-byseries

Reverse values in pd.Series by their value type


I have this pd.Series:

s = pd.Series([1, 'a', 1.4, 'b', 4, 98, 6.7, 'hello', 98.9])

My goal is to switch the values by each value type in reverse order.

My desired output is:

>>> s = pd.Series([98, 'hello', 98.9, 'b', 4, 1, 6.7, 'a', 1.4])
>>> s
0       98
1    hello
2     98.9
3        b
4        4
5        1
6      6.7
7        a
8      1.4
dtype: object
>>> 

As you can see, the different value types are still in mixed order, but they are reversed by the other same type values.

  • The integer order was 1, 4, 98 and it's now 98, 4, 1.

  • The float order was 1.4, 6.7, 98.9 and it's now 98.9, 6.7, 1.4.

  • The string order was 'a', 'b', 'hello' and it's now 'hello', 'b', 'a'

What I have tried so far is:

>>> s.to_frame().groupby([[*map(type, s)]], sort=False).apply(lambda x: x.iloc[::-1]).reset_index(drop=True)
       0
0     98
1      4
2      1
3  hello
4      b
5      a
6   98.9
7    6.7
8    1.4
>>> 

And yes, they do get reversed in order. But, since I'm using groupby, the values are grouped together into separated groups, they're not mixed together.

How would I fix this?


Solution

  • out = (s.groupby(s.map(type), sort=False)
           .apply(lambda x: pd.Series(x.sort_values(ascending=False).tolist(), index=x.index)))
    

    out

    0       98
    1    hello
    2     98.9
    3        b
    4        4
    5        1
    6      6.7
    7        a
    8      1.4
    dtype: object