Find max values in a dict containing lists - python

The dict got the keys years and for each year it's a list of all the temperatures in all 12 months of that year. My goal is to print out a table starting with what year it is and then a new line for each month and the temp that month.
The main thing is to mark the highest temp of all years with (ATH) and mark the highest temp in each year with (YearHighest).
My current code:
temp_dict= {
"2010": [2, 3, 4, 5, 7, 3, 20, 29, 34, 2, 10, 1],
"2011": [2, 7, 4, 5, 9, 3, 20, 9, 34, 2, 10, 10]
}
for key in temp_dict:
print("Year",key,":")
x=0
for temps in temp_dict[key]:
x=x+1
print("Month "+str(x)+":%3d"%temps)
print()
I'm not sure how to make the max function, I was thinking something like this but I can't get it to work:
for key in temp_dict:
ATH = temp_dict[key]
YearHigh = temp_dict[key][0]
for temps in temp_dict[key]:
if temps >= temp_dict[key][0]:
YearHigh = temps
if YearHigh >= ATH:
ATH = YearHigh
How I want my output to look like:
Year 2011 :
Month1: 2
Month2: 7
Month3: 4
Month4: 5
Month5: 9
Month6: 3
Month7: 20
Month8: 9
Month9: 34 (YearHighest)(ATH)
Month10: 2
Month11: 10
Month12: 10
Year 2010 :
Month1: 2
Month2: 3
Month3: 4
Month4: 5
Month5: 7
Month6: 3
Month7: 20
Month8: 29
Month9: 34 (YearHighest)(ATH)
Month10: 2
Month11: 10
Month12: 1

Python has built-in function max, it's considered a good practice to use it.
Max in year:
max(temp_dict["2010"])
Max all time:
max(sum(temp_dict.values(), []))
sum(lists, []) does list flattening, equivalent to
[] + lists[0] + lists[1]...

Python has a builtin function max you can utilize:
for key in temp_dict:
print("Year", key,":")
temps = temp_dict[key]
max_temp = max(temps)
max_index = temps.index(max_temp)
for index, temps in enumerate(temps):
r = "Month "+str(index+1)+":%3d"%temps
if index == max_index:
r += "(YearHighest)(ATH)"
print(r)

You can try something like this:
temp_dict= {
"2010": [2, 3, 4, 5, 7, 3, 20, 29, 34, 2, 10, 1],
"2011": [2, 7, 4, 5, 9, 3, 20, 9, 34, 2, 10, 10]
}
# defines the max of all years with a list comprehension
global_max_temp = max([ max(year_temps) for year_temps in temp_dict.values() ])
# iterates through each year
for year, temps in temp_dict.items():
print("Year {}".format(year))
for i, temp in enumerate(temps):
# prepares the output
temp_string = ["Month{}: {}".format(i+1, temp)]
# builds a list of flags to be displayed
flags = []
if temp == max(temps):
# max in year flag
flags.append("YearHighest")
if temp == global_max_temp:
# absolute max flag
flags.append("ATH")
# joins temp_string and flags in a single line and prints it
print(" ".join(temp_string + [ "({})".format(flag) for flag in flags ]))
Useful links from Python's documentation: enumerate, list comprehensions, max

This is my code.
temp_dict= {
"2010": [2, 3, 4, 5, 7, 3, 20, 29, 34, 2, 10, 1],
"2011": [2, 7, 4, 5, 9, 3, 20, 9, 34, 2, 10, 10]
}
# Find the highest temp of all years
ath = max([ max(v) for v in temp_dict.values()])
for key in temp_dict:
# Output Year
print("Year{k}:".format(k=key))
x=0
# Find max
max_value = max(temp_dict[key])
for temps in temp_dict[key]:
# Output Month
x=x+1
s = "Month {x}:{v:3d}".format(x=str(x), v=temps)
# Tag the max value
if max_value == temps:
s += "(YearHighest)"
if ath == temps:
s += "(ATH)"
print(s)
print()
And this is my output.
Year2010:
Month 1: 2
Month 2: 3
Month 3: 4
Month 4: 5
Month 5: 7
Month 6: 3
Month 7: 20
Month 8: 29
Month 9: 34(YearHighest)(ATH)
Month 10: 2
Month 11: 10
Month 12: 1
Year2011:
Month 1: 2
Month 2: 7
Month 3: 4
Month 4: 5
Month 5: 9
Month 6: 3
Month 7: 20
Month 8: 9
Month 9: 34(YearHighest)(ATH)
Month 10: 2
Month 11: 10
Month 12: 10
Here needs to use max function. It can max value from numbers of a list fast.

Related

Pandas group by selected dates

I have a dataframe that is very similar to this dataframe:
index
date
month
0
2019-12-1
12
1
2020-03-1
3
2
2020-07-1
7
3
2021-02-1
2
4
2021-09-1
9
And i want to combine all dates that are closest to a set of months. The months need to be normalized like this:
Months
Normalized month
3, 4, 5
4
6, 7, 8, 9
8
1, 2, 10, 11, 12
12
So the output will be:
index
date
month
0
2019-12-1
12
1
2020-04-1
4
2
2020-08-1
8
3
2020-12-1
12
4
2021-08-1
8
You can iterate through the DataFrame and use replace to change the dates.
import pandas as pd
df = pd.DataFrame(data={'date': ["2019-12-1", "2020-03-1", "2020-07-1", "2021-02-1", "2021-09-1"],
'month': [12,3,7,2,9]})
for index, row in df.iterrows():
if (row['month'] in [3,4,5]):
df['month'][index] = 4
df["date"][index] = df["date"][0].replace(df["date"][0][5:7],"04")
elif (row['month'] in [6,7,8,9]):
df['month'][index] = 8
df["date"][index] = df["date"][0].replace(df["date"][0][5:7],"08")
else:
df['month'][index] = 12
df["date"][index] = df["date"][0].replace(df["date"][0][5:7],"12")
you can try creating a dictionary of months where:
norm_month_dict = {3: 4, 4: 4, 5: 4, 6: 8, 7: 8, 8: 8, 9: 8, 1: 12, 2: 12, 10: 12, 11: 12, 12: 12}
then use this dictionary to map month values to their respective normalized month values.
df['normalized_months'] = df.months.map(norm_month_dict)
You need to construct a dictionary from the second dataframe (assuming df1 and df2):
d = (
df2.assign(Months=df2['Months'].str.split(', '))
.explode('Months').astype(int)
.set_index('Months')['Normalized month'].to_dict()
)
# {3: 4, 4: 4, 5: 4, 6: 8, 7: 8, 8: 8, 9: 8, 1: 12, 2: 12, 10: 12, 11: 12, 12: 12}
Then map the values:
df1['month'] = df1['month'].map(d)
output:
index date month
0 0 2019-12-1 12
1 1 2020-03-1 4
2 2 2020-07-1 8
3 3 2021-02-1 12
4 4 2021-09-1 8`

selecting data from list whiles keeping the order

trying to select subset from a list, however the order is reversed after selection
tried using pandas isin
df.mon =[1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12,...]
# selecting
results = df[df.month.isin([10,11,12,1,2,3])]
print(results.mon]
mon = [1,2,3,10,11,12, 1,2,3,10,11,12,...]
desired results
mon= [10,11,12,1,2,3,10,11,12,1,2,3,...]
# sorting results in this
mon = [1,1,2,2,3,3,10,10,11,11,12,12] and I dont want that either
thanks for the help
I work most with basic python lists, so I have converted the df to a list.
Data
The data is displayed in an xlsx file like this.
The input is a xlsx document which goes 1, 2, .. 12, 1, 2, .. 12 only twice, the "Values" start at 90 and count by 10 all the way out to the second 12.
Process
import pandas as pd
df = pd.read_excel('Book1.xlsx')
arr = df['Column'].tolist()
arr2 = df['Values'].tolist()
monthsofint = [10, 11, 12, 1, 2, 3]
locs = []
dictor = {}
for i in range(len(monthsofint)):
dictor[monthsofint[i]] = []
for i in range(len(monthsofint)): # !! Assumption !!
for j in range(len(arr)):
if monthsofint[i] == arr[j]:
dictor[monthsofint[i]].append(j)
newlist = []
newlist2 = []
for i in range(len(dictor[monthsofint[0]])):
for j in range(len(monthsofint)):
newlist.append(arr[dictor[monthsofint[j]][i]])
newlist2.append(arr2[dictor[monthsofint[j]][i]])
print(newlist)
print(newlist2)
Output: [10, 11, 12, 1, 2, 3, 10, 11, 12, 1, 2, 3] and [180, 190, 200, 90, 100, 110, 300, 310, 320, 210, 220, 230]
Note on Assumption: The assumption made is that there will always be 12 months for every year in the file.
In your case , we using Categorical + cumcount
#results = df[df.mon.isin([10, 11, 12, 1, 2, 3])].copy()
results.mon=pd.Categorical(results.mon,[10,11,12,1,2,3])
s=results.sort_values('mon')
s=s.iloc[s.groupby('mon').cumcount().argsort()]
s
Out[172]:
mon
9 10
10 11
11 12
0 1
1 2
2 3
21 10
22 11
23 12
12 1
13 2
14 3
I think you can take what we can have for each category, then use izip_longest to zip those lists.
So I found a relatively easy and simple way to do it from another source
For those who might be interested:
df[(df.index > 4) & (df.month.isin([10, 11, 12, 1, 2, 3]))]

I would like to make a veto map list in order to choose a map for scrimming?

Im new i guess and havent done python in like 6 months. I want a list of game maps (from overwatch), and then ask the user to remove a map from the list and then ask again until only 5 maps remain. Here is what I have and i honestly have no idea what im doing.
Hanamura = 1
Horizon_Lunar_Colony = 2
Temple_of_Anubis = 3
Volskaya_Industries = 4
Dorado = 5
Junkertown = 6
Rialto = 7
Route_66 = 8
Gibraltar = 9
Blizzard_World = 10
Eichenwalde = 11
Hollywood = 12
Kings_row = 13
Numbani = 14
Ilios = 15
Lijiang = 16
Nepal = 17
Oasis = 18
# (Hanamura, Horizon_Luner_Colony, Temple_of_Anubis, Volskaya_Industries,
Dorado, Junkertown, Rialto, Route_66, Gibraltar, Blizzard_World, Eichenwalde,
Hollywood, Kings_row, Numbani, Ilios, Lijiang, Nepal, Oasis)
# (Hanamura = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,15, 16, 17, 18)
print ('Hanamura0 \nHorizon_Lunar_Colony1 \nTemple_of_Anubis2
\nVolskaya_Industries3 \nDorado4 \nJunkertown5 \nRialto6 \nRoute_66_7
\nGibraltar8 \nBlizzard_World9 \nEichenwalde10 \nHollywood11 \nKings_row12
\nNumbani13 \nIlios14 \nLijiang15 \nNepal16 \nOasis 17\n')
p = 1
numbofitems = 18
if numbofitems >= 5:
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
x.remove(input())
print(x)
numbofitems - p
Try this:
maps = ['Hanamura',
'Horizon_Lunar_Colony',
'Temple_of_Anubis',
'Volskaya_Industries',
'Dorado',
'Junkertown',
'Rialto',
'Route_66',
'Gibraltar',
'Blizzard_World',
'Eichenwalde',
'Hollywood',
'Kings_row',
'Numbani',
'Ilios',
'Lijiang',
'Nepal',
'Oasis']
num = 5
while len(maps) >= num:
print("Map list:\n")
for m in maps: # Iterates on the maps list
print(m)
print("\n")
to_remove = input("Remove a map: ")
try: # Try to remove selected map from the list
maps.remove(to_remove)
print("\n{} map removed!\n".format(to_remove))
except: # An exception occurs if it's not in the list
print("\nSelected map not in the list!\n")
pass
print("{} in the list!\n".format(num))

Python: Is there a more efficient way to convert int value of months?

I have a list of integers [1, 2...40, 41...] that represent months of a few years. i.e. 1 is January of year 1, 13 is January of year 2, and so on. When trying to convert into just the month integer (all Januarys to 1, etc.) I'm using month_int % 12 but it turns December into 0. I wrote the following small block to catch the Decembers but was wondering if there's a more efficient way?
for month_int in month_list:
if not(bool(month_int % 12)):
# Dec exception here
else:
# work as normal
Basically, I want to change lists like this:
[1, 2...12, 13, 14, 15...]
[1, 2...12, 1, 2, 3...]
You are indexing from 1 instead of zero. What you can do is subtract 1 and then add 1 to the remainder again:
month = (month - 1) % 12 + 1
fodma1's answer has you covered, but you can do it even shorter:
month = month % 12 or 12
>>> l = [1, 2, 12, 13, 14, 15]
>>> [m % 12 or 12 for m in l]
[1, 2, 12, 1, 2, 3]
Since there are more months that aren't December it would be slightly more efficient to have that condition first e.g.
for month_int in month_list:
if (bool(month_int % 12)):
# normal
else:
# December
Since it will only move to the else once every 12 iterations then.

How to print a dictionary separated by commas

Let's say we have a dictionary
dict = { 'Dollar': 12, 'Half-Coin': 4, 'Quarter': 3, 'Dime': 7 }
How would I go about printing the code so it looks like:
Dollar 12, Half-Coin 4, Quarter 3, Dime 7
Use ','.join(), passing in a generator of strings.
d = { 'Dollar': 12, 'Half-Coin': 4, 'Quarter': 3, 'Dime': 7 }
print ', '.join('{} {}'.format(k,v) for k,v in d.items())
Result:
Half-Coin 4, Quarter 3, Dollar 12, Dime 7
If you want the results to be in a predictable order, you'll need to sort the items.
order=('Dollar', 'Half-Coin', 'Quarter', 'Dime')
d = { 'Dollar': 12, 'Half-Coin': 4, 'Quarter': 3, 'Dime': 7 }
print ', '.join('{} {}'.format(k,d[k]) for k in sorted(d, key=order.index))
Result:
Dollar 12, Half-Coin 4, Quarter 3, Dime 7
Ps. Don't name your variables with names of builtin types. Your name eclipses the builtin name, so subsequent code won't be able to call dict(), for example.
", ".join([x +" "+str(dict[x]) for x in dict.keys()])
dict = { 'Dollar': 12, 'Half-Coin': 4, 'Quarter': 3, 'Dime': 7 }
out=""
for i in dict:
out += i+" "+str(dict[i])+", "
print out[:-2]
result:
Half-Coin 4, Quarter 3, Dollar 12, Dime 7

Categories

Resources