Pravin Mishra
Pravin Mishra

Reputation: 31

Better solution or optimising for loop python

My dataset is like this :

[{'Date': '22-Aug-2019', 'Open': 10905.3, 'High': 10908.25, 'Low': 10718.3, 'Close': 10741.35, 'Shares Traded': 668193449, 'Turnover (Rs. Cr)': 18764.38},
{'Date': '23-Aug-2019', 'Open': 10699.6, 'High': 10862.55, 'Low': 10637.15, 'Close': 10829.35, 'Shares Traded': 667079625, 'Turnover (Rs. Cr)': 20983.75}, {'Date': '26-Aug-2019', 'Open': 11000.3, 'High': 11070.3, 'Low': 10756.55, 'Close': 11057.85, 'Shares Traded': 684141923, 'Turnover (Rs. Cr)': 22375.99}]

I want daywise average,Min,Max from this dataset as my output which i did.

for share in dataset:
    day_name = datetime.datetime.strptime(share['Date'], "%d-%b-%Y").strftime('%A')
    if day_name not in day_wise.keys():
        day_wise[day_name] = {'avg':0, 'min':9999999999, 'max':0}

        if share['Turnover (Rs. Cr)'] > day_wise[day_name]['max']:
            day_wise[day_name]['max'] = share['Turnover (Rs. Cr)']
        if share['Turnover (Rs. Cr)'] < day_wise[day_name]['min']:
            day_wise[day_name]['min'] = share['Turnover (Rs. Cr)']
        day_wise[day_name]['avg'] += share['Turnover (Rs. Cr)']

    else:
        if share['Turnover (Rs. Cr)'] > day_wise[day_name]['max']:
            day_wise[day_name]['max'] = share['Turnover (Rs. Cr)']
        if share['Turnover (Rs. Cr)'] < day_wise[day_name]['min']:
            day_wise[day_name]['min'] = share['Turnover (Rs. Cr)']
        day_wise[day_name]['avg'] += share['Turnover (Rs. Cr)']         
return Response(day_wise)

But i want to optimize it , Like less number of lines of code and more fast performance.

Upvotes: 0

Views: 87

Answers (2)

Christian Gomes
Christian Gomes

Reputation: 326

One simple e elegant way to reduce your code is using DataFrame. Like this:

import pandas as pd
import calendar

df_data = pd.DataFrame(dataset)

# Convert to day week name
df_data["Date"] = pd.to_datetime(df_data["Date"])
df_data["Date"] = df_data["Date"].apply(lambda x: calendar.day_name[x.weekday()])

day_wise = {}
for name, group in df_data.groupby('Date'):
    day_wise[name] = {
        "avg": group["Turnover (Rs. Cr)"].sum(),
        "min": group["Turnover (Rs. Cr)"].min(),
        "max": group["Turnover (Rs. Cr)"].max()
    }
>> day_wise
{'Friday': {'avg': 20983.75, 'min': 20983.75, 'max': 20983.75},
 'Monday': {'avg': 22375.99, 'min': 22375.99, 'max': 22375.99},
 'Thursday': {'avg': 18764.38, 'min': 18764.38, 'max': 18764.38}}

Note that, i use sum() instead of avg(), since your example only performs the sum. If you want the mean (i.e., avg), just change the sum() for mean() in the code.

Upvotes: 1

sushanth
sushanth

Reputation: 8302

If u can use pandas, try this.

Load the dict to pandas dataframe, apply groupby on Date & aggregate on the numeric column then use to_dict to convert dataframe back to dict.

import pandas as pd

>>> df = pd.DataFrame(data)

          Date     Open      High       Low     Close  Shares Traded  Turnover (Rs. Cr)
0  22-Aug-2019  10905.3  10908.25  10718.30  10741.35      668193449           18764.38
1  23-Aug-2019  10699.6  10862.55  10637.15  10829.35      667079625           20983.75
2  26-Aug-2019  11000.3  11070.30  10756.55  11057.85      684141923           22375.99

>>> df['Day'] = pd.to_datetime(df['Date'], format="%d-%b-%Y").dt.strftime("%A")

>>> df_g = df.groupby('Day')['Turnover (Rs. Cr)'].agg(['min','max','mean'])

               min       max      mean
Day                                   
Friday    20983.75  20983.75  20983.75
Monday    22375.99  22375.99  22375.99
Thursday  18764.38  18764.38  18764.38

>>> df_g.to_dict(orient='index')

{'Friday': {'max': 20983.75, 'mean': 20983.75, 'min': 20983.75},
 'Monday': {'max': 22375.99, 'mean': 22375.99, 'min': 22375.99},
 'Thursday': {'max': 18764.38, 'mean': 18764.38, 'min': 18764.38}}

Upvotes: 1

Related Questions