[PYTHON] Mes pandas trop tard?

introduction

Si vous utilisez d'une manière ou d'une autre la trame de données pandas devant la putain de grosse matrice, la mémoire sera insuffisante et le traitement prendra des heures. Par conséquent, je garderai un mémorandum de points dont je prends personnellement soin lors de la manipulation de trames de données plus légères et plus rapides.

Mokuji

Optimisation de type

kaggle Cette fonction n'a jamais été vue dans une compétition de table. Optimisez la taille du moule pour éviter la perte de mémoire et accélérer

def reduce_mem_usage(df):
    start_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage of DataFrame is {:.2f} MB'.format(start_mem))
    
    for col in df.columns:
        col_type = df[col].dtype
        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)  
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)

    end_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    return df

Spécifiez le type avec read_csv

En spécifiant le type ici, le temps de spécifier le type peut être omis et les données peuvent être lues plus rapidement. Pas très adapté aux données avec des colonnes trop grandes (difficile)

df = pd.read_csv('./train.csv', dtype={'a': int, 'b': float, 'c': str})

ne pas utiliser pour

python est lent car le compilateur s'exécute pour chaque processus pour chacun des for. Par conséquent, for n'est pas utilisé autant que possible, et map et ʻapply` sont utilisés.

D'ailleurs, j'utilise correctement ces fonctions comme suit, mais je ne sais pas ce qui est réellement différent (qui me le dit)

map

Lors de l'adaptation d'un type de dictionnaire à une colonne

d = {'hoge':'Hoge', 'fuga':'Fuga', 'piyo':'Piyo'}

df['tmp'] = df['tmp'].map(d)

apply

Lors de l'application d'une fonction à des données ciblées par groupby

df['rolling_mean'] = df.groupby([id])['timeseries'].apply(lambda x:x.rolling(12, 1).mean())

Lorsque vous souhaitez traiter les données d'une ligne

def cos_sim(v1, v2):
    return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))

df = df.apply(lambda x: cos_sim(v1, x), axis=1) # return pd.Series

Les deux peuvent traiter les colonnes, vous pouvez donc les utiliser selon votre humeur.

Au fait, la sensation de température de for en python personnel 100 iter → Ça va. 1000 iter → Hmm? 10000 iter → Hé ... 100000 iter → Êtes-vous sain d'esprit?

prime

Il y a des choses comme "J'ai traité chaque catégorie, mais je ne peux pas utiliser map, ʻapply` ... Cela prend beaucoup de temps pour essayer et je ne peux pas attendre ...".

year_list = [2010, 2011, 2012, 2013]

for y in year_list:
    df_y = df[df['year']==y]

    '''En traitement'''

    df_y_executed.to_csv('./savefolder/save_{y}.csv'.format(y=y))

Actuellement, les pandas ne sont pas parallélisés par des cœurs physiques, il y a donc des ressources excédentaires, mais le temps d'attente est un gaspillage. Par conséquent, il est parallélisé de force par le noyau physique.

Dans un tel cas, la méthode suivante est utilisée dans mon laboratoire.

  1. Divisez la catégorie et enregistrez-la en csv (dans l'exemple ci-dessus, divisez-la comme [2010, 2011], [2012, 2013] et enregistrez-la en csv)
  2. Démarrez un autre jupyter et exécutez le processus avec deux jupyters

Cela permet de traiter à l'aide de deux cœurs physiques.

Résumé

Il y a quelque chose qui s'appelle Dask dans Chimata, et il semble que les données plus grandes que la mémoire puissent être traitées en parallèle. J'ai entendu dire qu'il est hautement compatible avec les pandas et qu'il se sent bien, alors j'aimerais l'essayer.

Recommended Posts

Mes pandas trop tard?
Mes pandas (Python)
[Astuces] Ma note Pandas
Pandas