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.
read_csv
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
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})
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
groupby
df['rolling_mean'] = df.groupby([id])['timeseries'].apply(lambda x:x.rolling(12, 1).mean())
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?
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.
Cela permet de traiter à l'aide de deux cœurs physiques.
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.