J'ai environ 20000 documents dans les sous-répertoires. Et je voudrais les lire tous et les ajouter comme une liste de listes. Ceci est mon code jusqu'à présent, Cependant, cela est inefficace et il faut beaucoup de temps pour lire et les ajouter dans la liste DF. Ma sortie attendue est, p> df= [[doc1], [doc2], [doc3], [doc4],......,[doc20000]]
3 Réponses :
Les fonctions génératrices vous permettent de déclarer une fonction qui se comporte comme un itérateur, c'est-à-dire qu'il peut être utilisé dans une boucle pour la boucle. P>
Générateurs P>
générateur de fonctions paresseux p>
xxx pré> blockQuote>
Ce n'est pas un gros fichier. Ce jeu de données contient 20000 dossiers de sous-répertoires. Mon objectif est de les lire un par un et de les annoncer dans une liste de listes.
OK, il y a un lecteur () qui mettez des données dans DataFrame et écrivez en CSV.
Il n'y a que tant que vous pouvez faire pour accélérer l'accès des disques. Vous pouvez utiliser des threads pour chevaucher des opérations de lecture de fichier avec le (code> latin1 code> le recode et le nouveau remplacement de la nouvelle ligne. Mais de manière réaliste, cela ne fera pas une énorme différence.
import multiprocessing.pool
MEG = 2**20
filelist = []
topics =os.listdir(my_directory)
for topic in topics:
files = os.listdir (my_directory+ '/'+ topic)
print(files)
for file in files:
print(file)
filelist.append(my_directory+ '/'+ topic+ '/'+file)
def worker(filename):
with open(filename, encoding ='latin1', bufsize=1*MEG) as f:
data = f.read().replace('\n', ' ')
#print(data)
return data
with multiprocessing.pool.ThreadPool() as pool:
datalist = pool.map(worker, filelist, chunksize=1)
df = np.array(datalist)
Peut-il être fait avec MPI aussi? Pouvez-vous suggérer une solution basée sur MPI?
Bien sûr, mais je pense que MPI serait plus lent, car vous devriez copier des données entre les processus. Cette tâche est probablement E / S lié et simplement laisser un thread d'attente de se lit comme une autre conversion est à propos du meilleur que vous obtiendrez.
J'ai mal lu la ligne On dirait que votre question peut ne pas résoudre votre problème réel.
Avez-vous mesuré la performance de vos deux appels les plus importants? P>
La façon dont vous avez formaté votre code me fait penser qu'il y a un bug: Comme d'habitude, les performances lentes peuvent être abordées en jetant plus de mémoire au problème. Si vous avez suffisamment de mémoire pour charger La clé est de ne pas traiter d'une opération de pandas tant que vous n'avez pas chargé toutes les données. Ce n'est qu'alors que vous pouvez utiliser Une belle question qui a un peu plus de discussion que j'ai trouvée:
Améliorer les performances de la ligne Ajout sur Pandas Dataframes P>
df = np.append (df, données) code> et j'ai supposé que vous êtes ajouté à la mataframe, pas à la matrice numérique. Donc, mon commentaire est un peu non pertinent mais je le laissais pour d'autres que mon mal aime-moi comme moi ou que j'ai un problème similaire avec les pandas 'DataFrame ANNEX. P>
Problème réel H1>
fichiers = os.listdir (my_directory + '/' + sujet) code> li>
df = np.append (df, données) code> li>
ul>
df = np.append (df, données) code> est en dehors de la portée de la boucle afin que je ne pense que votre dernier Les données code> sont annexées à votre cadre de données. Si ce n'est juste un problème avec le formatage du code ici dans le poteau et que vous appendez vraiment 20k fichiers à votre trame de données, cela peut être le problème - Ajout au DataFrame code> est lent. P>
Solution potentielle h1>
tout code> des fichiers à l'avance et que vous ne les insérez que dans un fichier de données ceci pourrait s'avérer plus rapide. P>
dataframe code> 's de_records code> ou l'une de ses autres méthodes d'usine. P>
TL; DR H1>
Dataframe < / code>, dites dataframe.from_records code> li>
ol>
Je remarque que vous avez signalé cela comme «apprentissage de la machine» et, en tant que tel, je ne répondrai pas à votre question exactement, mais donnez quelques suggestions. Il s'agit généralement d'une mauvaise pratique de charger toutes vos données simultanément en mémoire, d'autant plus que vous pouvez effectuer des lectures pendant que vous effectuez vos autres calculs. Vous devez utiliser le module multiprocessionnant pour tirer parti d'un autre noyau pour aller et collecter les lots N SUIVANT N'EST Pendant que votre modèle est composé de gradients informatiques (ou quoi que ce soit). Sinon, votre code a l'air bien (pourrait être amélioré avec les gestionnaires de contexte), mais il doit être multi-fileté.
En tant que mis à part, depuis
df = np.append (df, données) code> est en dehors de la boucle, vous jetez tout sauf les dernières donnéescode>.L'ouverture de 20 000 fichiers texte prend beaucoup de temps en soi. Peut-être que vous pourriez écrire un code séparé pour convertir celles à quelque chose comme 100 fichiers CSV qui sont beaucoup plus rapides à lire?
Supprimer le
Imprimer (Données) CODE> Appelez-vous dans la boucle. Les trucs d'impression prennent une durée étonnamment longue et de tout le défilement, et il peut être encore plus lent si vous exécutez le script dans une IDE ou autre chose que le terminal.Quelle est la taille de ces fichiers et avez-vous assez de bélier pour les tenir? Il ne faut pas prendre des heures pour lire suffisamment de données pour submerger votre RAM. À un moment donné, vous pouvez commencer à battre le fichier d'échange, mais éventuellement tout va faire exploser.
J'ai 16 Go de RAM, chaque fichier est d'environ 4 Ko-10 Ko, ils contiennent des courriels.
Oh, et @kindall a la meilleure suggestion de tous.
Ce n'est que quelques centaines de Megs .... Les lectures de fichier doivent être effectuées à la minute, pas d'heures. Ceci est un disque dur local?
Oui, j'utilise mon propre PC et toutes les données du disque dur local.
Je ne sais pas combien de copie est faite dans
df = np.append (df, données) code>. Vous serez peut-être mieux avec une liste de python régulière et la création de la matrice NP une fois à la fin lorsque vous connaissez la taille.