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}}
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
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}}
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