Currency pair strength list based on dataframe row values

Question:

Based on the following currency strength rankings dataframe:

                    EUR USD GBP JPY AUD CHF CAD NZD
2023-02-24 12:00:00 5.0 8.0 4.0 3.0 2.0 7.0 6.0 1.0
2023-02-24 13:00:00 6.0 8.0 4.0 3.0 2.0 7.0 5.0 1.0
2023-02-24 14:00:00 7.0 8.0 4.0 3.0 2.0 6.0 5.0 1.0
2023-02-24 15:00:00 7.0 8.0 6.0 2.0 3.0 5.0 4.0 1.0

How to calculate and return a list of strongest to weakest currency pairs for each row?

Desired output

For example on the last row the strongest currency pair would be "USD_NZD" as USD has the highest rank and NZD the lowest.

['USD_NZD', 'USD_JPY'] then all other currency pairs

Data

{'EUR': {Timestamp('2023-02-24 12:00:00'): 5.0,
  Timestamp('2023-02-24 13:00:00'): 6.0,
  Timestamp('2023-02-24 14:00:00'): 7.0,
  Timestamp('2023-02-24 15:00:00'): 7.0},
 'USD': {Timestamp('2023-02-24 12:00:00'): 8.0,
  Timestamp('2023-02-24 13:00:00'): 8.0,
  Timestamp('2023-02-24 14:00:00'): 8.0,
  Timestamp('2023-02-24 15:00:00'): 8.0},
 'GBP': {Timestamp('2023-02-24 12:00:00'): 4.0,
  Timestamp('2023-02-24 13:00:00'): 4.0,
  Timestamp('2023-02-24 14:00:00'): 4.0,
  Timestamp('2023-02-24 15:00:00'): 6.0},
 'JPY': {Timestamp('2023-02-24 12:00:00'): 3.0,
  Timestamp('2023-02-24 13:00:00'): 3.0,
  Timestamp('2023-02-24 14:00:00'): 3.0,
  Timestamp('2023-02-24 15:00:00'): 2.0},
 'AUD': {Timestamp('2023-02-24 12:00:00'): 2.0,
  Timestamp('2023-02-24 13:00:00'): 2.0,
  Timestamp('2023-02-24 14:00:00'): 2.0,
  Timestamp('2023-02-24 15:00:00'): 3.0},
 'CHF': {Timestamp('2023-02-24 12:00:00'): 7.0,
  Timestamp('2023-02-24 13:00:00'): 7.0,
  Timestamp('2023-02-24 14:00:00'): 6.0,
  Timestamp('2023-02-24 15:00:00'): 5.0},
 'CAD': {Timestamp('2023-02-24 12:00:00'): 6.0,
  Timestamp('2023-02-24 13:00:00'): 5.0,
  Timestamp('2023-02-24 14:00:00'): 5.0,
  Timestamp('2023-02-24 15:00:00'): 4.0},
 'NZD': {Timestamp('2023-02-24 12:00:00'): 1.0,
  Timestamp('2023-02-24 13:00:00'): 1.0,
  Timestamp('2023-02-24 14:00:00'): 1.0,
  Timestamp('2023-02-24 15:00:00'): 1.0}}
Asked By: nipy

||

Answers:

IIUC you may want to use:

list(map("_".join, zip(df.idxmax(1), df.idxmin(1))))

Output:

['USD_NZD', 'USD_NZD', 'USD_NZD', 'USD_NZD']

If you want the values you can use:

list(zip(df.max(1), df.min(1)))

Out:

[(8.0, 1.0), (8.0, 1.0), (8.0, 1.0), (8.0, 1.0)]

If you want all the pairs sorted by abs difference, you could use the following:

from itertools import combinations

f = lambda r: list(
    map(
        lambda x: x[0][0] + "_" + x[1][0],
        sorted(
            combinations(sorted(zip(r.index, r.values), key=lambda x: -x[1]), 2),
            key=lambda t: t[0][1] - t[1][1],
            reverse=True,
        ),
    )
)
out = df.apply(f, axis=1)

print(out)

2023-02-24 12:00:00    [USD_NZD, USD_AUD, CHF_NZD, USD_JPY, CHF_AUD, ...
2023-02-24 13:00:00    [USD_NZD, USD_AUD, CHF_NZD, USD_JPY, CHF_AUD, ...
2023-02-24 14:00:00    [USD_NZD, USD_AUD, EUR_NZD, USD_JPY, EUR_AUD, ...
2023-02-24 15:00:00    [USD_NZD, USD_JPY, EUR_NZD, USD_AUD, EUR_JPY, ...
dtype: object
Answered By: SomeDude
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.