1

Dict of df's:

years = [2017, 2018, 2019]
dfcols = ['Count', 'Amount']
dataframedict = {'CatA': pd.DataFrame(data=[[1, 5], [2, 6], [3, 7]], columns=dfcols, index=years), 
                'CatB': pd.DataFrame(data=[[4, 8], [5, 9], [6, 19]], columns=dfcols, index=years), 
                'CatC': pd.DataFrame(data=[[7,11], [8,12], [9,13]], columns=dfcols, index=years)}

Need a list of dict keys sorted descending by 'Amount' in 2019, so ['CatB', 'CatC', 'CatA']

Tried, following this variations of:

for k in sorted(dataframedict, key=lambda df: df.Amount[-1], reverse=True):
    print(k)

Getting error: AttributeError: 'str' object has no attribute 'Amount'

Thanks

shanlodh
  • 1,015
  • 2
  • 11
  • 30

2 Answers2

2

If you just want a list, you can use a list comprehension and the .items method of the dictionary to retrieve the key and dataframe

[
    k for k, df 
    in sorted(dataframedict.items(), key=lambda x: x[1].Amount.iloc[-1], reverse=True)
]
# returns:
['CatB', 'CatC', 'CatA']
James
  • 32,991
  • 4
  • 47
  • 70
0

You can convert your dict to a sort list of tuples:

for k, v in sorted(dataframedict.items(), key=lambda x: x[1].Amount.iloc[-1], reverse=True):
    print(k)

Output:

CatB
CatC
CatA

Note that I am passing .items() to the sorted. Each one is a tuple of length 2 (x[0] is the key and x[1] is the value/df).

Now, regarding your error: When you pass a dict in sorted, the keys of the dict are considered:

>>> a = {1: "ad", 0: "ads"}
>>> sorted(a, key=lambda x: x)
[0, 1]

Thus you are passing strings in the lambda

urban
  • 5,392
  • 3
  • 19
  • 45
  • @James: You are not iterating a list of tuples so my `k` was a tuple. I have now unpacked it to key and value - EDIT: I see what you are saying - just copied the original code - not tested but seems that `iloc` solves the issue right? – urban Jan 02 '20 at 10:33
  • This still gives a key error, **not** from the dictionary, but from the trying to grab the `[-1]` index from the `Amount` column of the data frame. That index does not exist, so a `KeyError` arises. Does the for-loop work for you? – James Jan 02 '20 at 10:36
  • @James, fixed the `iloc` - Just took a while to get a terminal here :). I also think is good to provide an explanation on why the original error occurred (and why the df key error happens in the Amount) to make the answer complete – urban Jan 02 '20 at 10:38
  • Thanks to both this user and @James, I'm accepting this answer for the more detailed explanation and upvoting the other reply – shanlodh Jan 02 '20 at 10:45