Лучшая практика кодирования при использовании pandas? - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь улучшить свои методы кодирования при написании функций. Моя конечная цель - получить количество времени, которое потребовалось для выполнения sh типа задачи в конкретной c команде. У меня есть стартовый фрейм данных с кодом:

    data = {'Team':['A', 'A', 'A', 'B','B','B','A','B'], 'Time':[20, 21, 19, 18,17,15,22,25],'Type':['Bike', 'Car', 'Walk', 'Scooter','Bike', 'Car', 'Walk', 'Scooter']} 

   df_new = pd.DataFrame(data) 

Затем я пишу функцию вроде:

def timer(df):
    team_A = df[df['Team'] == 'A']
    team_A_time_total = team_A.Time.sum()

    team_A_biketime_ = (team_A[team_A['Type'] == 'Bike'].Time.sum() / team_A_time_total)
    team_A_cartime_ = (team_A[team_A['Type'] == 'Car'].Time.sum() / team_A_time_total)
    team_A_walktime_ = (team_A[team_A['Type'] == 'Walk'].Time.sum() / team_A_time_total)
    team_A_scootertime_ = (team_A[team_A['Type'] == 'Scooter'].Time.sum() / team_A_time_total)

    team_B = df[df['Team'] == 'B']
    team_B_time_total = team_A.Time.sum()

    team_B_biketime_ = (team_B[team_B['Type'] == 'Bike'].Time.sum() / team_A_time_total)
    team_B_cartime_ = (team_B[team_B['Type'] == 'Car'].Time.sum() / team_A_time_total)
    team_B_walktime_ = (team_B[team_B['Type'] == 'Walk'].Time.sum() / team_A_time_total)
    team_B_scootertime_ = (team_B[team_B['Type'] == 'Scooter'].Time.sum() / team_A_time_total)

    return team_A_biketime_,team_A_cartime_, team_A_walktime_, team_A_scootertime_,team_B_biketime_,team_B_cartime_, team_B_walktime_, team_B_scootertime_

Я знаю, что этот код можно написать более чистым способом, но у меня возникают трудности получить это правильно. Я попытался:

def timer(df):
    types = ['Bike','Car','Walk','Scooter']
    teams = ['A','B']

    for team in teams: 
        df_team = df[df['Team'] == team]
        df_team_time = df_team.Time.sum()
        for value in types:
            df_value = df_team[df_team['Type'] == value]
            df_value_time = df_value.Time.sum() / df_team_time
    return df_value_time

Это не кажется мне правильным.

Ответы [ 2 ]

0 голосов
/ 08 апреля 2020

Вы пишете функцию для выполнения чего-то, что pandas уже делает оптимизированным способом. Поэтому, где это возможно, вы должны пытаться использовать groupby с агрегатными функциями.

Таким образом, для простых агрегатов вы должны использовать

df_new.groupby(['Team', 'Type'])['Time'].agg(['sum', 'mean'])

, который производит этот вывод

              sum  mean
Team Type              
A    Bike      20  20.0
     Car       21  21.0
     Walk      41  20.5
B    Bike      17  17.0
     Car       15  15.0
     Scooter   43  21.5

Как только вы ознакомитесь с основами, вы сможете выполнять более сложные операции

summdf = df_new.groupby(['Team', 'Type'])['Time'].agg(['sum'])
summdf = summdf.reset_index()
summdf = summdf.rename(columns={'sum': 'team_type_sum'})
summdf['team_tot'] = summdf.groupby('Team')['team_type_sum'].transform('sum')
summdf['team_type_pct'] = summdf['team_type_sum'] / summdf['team_tot']

, что приводит к

  Team     Type  team_type_sum  team_tot  team_type_pct
0    A     Bike             20        82       0.243902
1    A      Car             21        82       0.256098
2    A     Walk             41        82       0.500000
3    B     Bike             17        75       0.226667
4    B      Car             15        75       0.200000
5    B  Scooter             43        75       0.573333

0 голосов
/ 08 апреля 2020

С точки зрения лучшей практики в pandas, похоже, вам нужно больше узнать о df.loc[]

Я думаю, это то, что вы хотите:

import pandas as pd

data = {'Team':['A', 'A', 'A', 'B','B','B','A','B'], 'Time':[20, 21, 19, 18,17,15,22,25],'Type':['Bike', 'Car', 'Walk', 'Scooter','Bike', 'Car', 'Walk', 'Scooter']} 

df_new = pd.DataFrame(data) 

def timer(df, team, type):

    return df.loc[df['Team']==team].loc[df['Type']==type]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...