Supérieure de la limite de mémoire?
Est-il une limite à la mémoire pour python? J'ai été en utilisant un script python pour calculer la moyenne des valeurs à partir d'un fichier qui est un minimum de 150 mo de gros.
En fonction de la taille du fichier je rencontre parfois un MemoryError
.
Peut plus de mémoire affectée à la python, donc je ne rencontre pas de l'erreur?
EDIT: actuellement, le Code ci-dessous
REMARQUE: La taille des fichiers varie considérablement (jusqu'à 20 go) la taille minimale de l'un fichier de 150 mo
file_A1_B1 = open("A1_B1_100000.txt", "r")
file_A2_B2 = open("A2_B2_100000.txt", "r")
file_A1_B2 = open("A1_B2_100000.txt", "r")
file_A2_B1 = open("A2_B1_100000.txt", "r")
file_write = open ("average_generations.txt", "w")
mutation_average = open("mutation_average", "w")
files = [file_A2_B2,file_A2_B2,file_A1_B2,file_A2_B1]
for u in files:
line = u.readlines()
list_of_lines = []
for i in line:
values = i.split('\t')
list_of_lines.append(values)
count = 0
for j in list_of_lines:
count +=1
for k in range(0,count):
list_of_lines[k].remove('\n')
length = len(list_of_lines[0])
print_counter = 4
for o in range(0,length):
total = 0
for p in range(0,count):
number = float(list_of_lines[p][o])
total = total + number
average = total/count
print average
if print_counter == 4:
file_write.write(str(average)+'\n')
print_counter = 0
print_counter +=1
file_write.write('\n')
- Pouvez-vous nous montrer votre script? J'ai traité des fichiers beaucoup plus volumineux en Python sans problèmes.
- Qu'est-ce que votre script essaie de faire? Il me semble que vous voulez pour calculer la valeur moyenne de chaque quatrième colonne dans chacun des fichiers d'entrée. Est ce que le droit?
- J'ai remarqué de différences significatives de performance en ce qui concerne la Mémoire lors de l'exécution de la même application en Python sur Windows (XP) et mac OS X/Linux. La performance du côté de Windows a tendance à être le pire.
Vous devez vous connecter pour publier un commentaire.
(C'est ma troisième réponse parce que j'ai mal compris ce que votre code a été fait dans mon original, et puis en fait, mais une petite erreur cruciale dans ma deuxième espérons que trois est un charme.
Modifications: Depuis ce qui semble être une réponse, j'ai fait quelques modifications pour améliorer sa mise en œuvre au fil des ans, la plupart des pas trop grands. C'est donc, si des gens l'utiliser en tant que modèle, il fournira une base encore meilleure.
Comme d'autres l'ont souligné, votre
MemoryError
problème est probablement parce que vous tentez de lire le contenu entier de gros fichiers dans la mémoire et, en plus, ce qui permet de doubler la quantité de mémoire nécessaire à la création d'une liste de listes de la chaîne de valeurs de chaque ligne.Python mémoire limites sont déterminées par la quantité de ram physique et mémoire virtuelle de l'espace disque de votre ordinateur et système d'exploitation sont disponibles. Même si vous ne l'utilisez pas tout votre programme de "travaux", en utilisant, il peut être difficile car il prend trop de temps.
De toute façon, le moyen le plus évident d'éviter cette situation est de traiter chaque fichier une seule ligne à la fois, ce qui signifie que vous avez à faire le traitement de manière incrémentale.
Pour ce faire, une liste de fonctionnement totaux pour chacun des champs est conservé. Lorsque cela est terminé, la valeur moyenne de chaque champ peut être calculé en divisant le correspondant de la valeur totale par le nombre total de lignes à lire. Une fois que c'est fait, ces moyennes peuvent être imprimées et certains écrits de l'un des fichiers de sortie. J'ai aussi fait un effort conscient pour une utilisation très descriptif, les noms de variables pour essayer de le rendre compréhensible.
totals
etfield
sont str objets; nous voulons numérique totaux pour calculer les moyennes; votre totaux vont se développer dans certaines très longues chaînes; c'est Python, pas awk; vous avez besoin de jeter un peu defloat()
s y (d)totals = [field for field in fields]
au lieu detotals = fields
???totals = [field for...
était juste un objet à partir d'un point dans mon codage où je pensais que j'avais besoin d'une copie de la liste des champs.Vous êtes en train de lire tout le fichier en mémoire (
line = u.readlines()
) qui va échouer bien sûr, si le fichier est trop gros (et vous dire que certains sont jusqu'à 20 GO), donc, c'est votre problème.Mieux itérer sur chaque ligne:
est l'approche recommandée.
Plus tard dans votre script, vous êtes en train de faire des choses très étranges comme premier comptage de tous les éléments dans une liste, puis de la construction d'un
for
en boucle sur la plage de comptage. Pourquoi ne pas parcourir la liste directement? Quel est le but de votre script? J'ai l'impression que cela pourrait être fait beaucoup plus facile.C'est l'un des avantages des langages de haut niveau comme Python (par opposition à "C", où vous avez à faire ces tâches d'entretien vous-même): Permettre à Python pour gérer itération pour vous, et seulement de recueillir en mémoire ce que vous avez réellement besoin d'avoir en mémoire à un moment donné.
Aussi, comme il semble que vous êtes de traitement des fichiers TSV (tableur-separated values), vous devriez jeter un oeil à la
csv
module qui se chargera de tout le fractionnement, la suppression de\n
s etc. pour vous.Python, il est possible d'utiliser toute la mémoire disponible à son environnement. Mon simple "test de la mémoire" se bloque sur ActiveState Python 2.6 après l'utilisation sur
Sur python 2.5, il se bloque de plus en plus tôt:
sans doute, je peux configurer Jython à utiliser plus de mémoire (il utilise les limites de la JVM)
Application de Test:
Dans votre application vous lire tout le fichier à la fois. Pour ces gros fichiers, vous devriez lire le ligne par ligne.
Non, il n'y a pas de Python-limite spécifique sur l'utilisation de la mémoire d'une application en Python. J'ai l'habitude de travailler avec Python applications qui peuvent utiliser plusieurs giga-octets de mémoire. Très probablement, votre script utilise plus de mémoire que ce qui est disponible sur la machine que vous utilisez.
Dans ce cas, la solution consiste à réécrire le script pour être plus efficace en terme de mémoire, ou pour ajouter plus de mémoire physique si le script est déjà optimisé pour minimiser l'utilisation de la mémoire.
Edit:
Votre script lit l'intégralité du contenu de vos fichiers dans la mémoire à la fois (
line = u.readlines()
). Puisque vous êtes de traitement des fichiers jusqu'à 20 GO en taille, vous allez obtenir des erreurs de mémoire avec cette approche, sauf si vous avez d'énormes quantités de mémoire de votre machine.Une meilleure approche serait de lire les fichiers d'une ligne à la fois:
Non seulement vous êtes la lecture de l'ensemble de chaque fichier dans la mémoire, mais aussi vous laborieusement répliquer les informations dans une table appelée
list_of_lines
.Vous avez un problème secondaire: votre choix de noms de variables gravement dissimuler ce que vous faites.
Voici votre script réécrit avec le readlines() caper retiré et avec des noms significatifs:
Il devient rapidement évident que (1) vous êtes à la colonne de calcul des moyennes (2) l'obscurcissement conduit certains autres pensent que vous étiez le calcul de la ligne moyenne.
Que vous êtes à la colonne de calcul des moyennes, aucune sortie n'est requis jusqu'à la fin de chaque fichier, et la quantité de mémoire nécessaire est proportionnelle au nombre de colonnes.
Ici est une version révisée de la boucle externe code:
float
les valeurs lues dans une liste séparée, ni faire de leur (colonnes) totaux nombre réel -- seulement besoin de s'assurer que leurs valeurs moyennes sont calculées dans ce format.values = map(float, values)
: j'ai horreur de ces typeshifting. Deuxième point: comment peut-colonne des totaux de ne pas être flotteurs????float
est probablement correct, ce qui serait, en effet, exiger que le total de l'être, trop.row_count
commence à1
, de sorte que leif not row_count:
d'initialisation ne sera jamais exécutée.