2017-09-21 8 views
3

J'utilise Pandas module dans python 3.5 pour lire des tableaux croisés récursivement à partir de sous-répertoires et je veux concaténer les tableaux croisés dans la boucle for après avoir appelé pd.crosstab() et après la boucle for écrire la sortie dans un fichier Excel. J'ai essayé de copier table1 dans table3 (voir le code ci-dessous) après que j'appelle pd.crosstab(), mais si certaines valeurs ne sont pas présentes dans les derniers fichiers de données, table3 montre NaN pour ces entrées. J'ai regardé pd.concat, mais je ne trouve pas un exemple de comment l'utiliser dans une boucle for.Comment concaténer des tableaux croisés lors de la lecture d'une boucle for dans pandas

Les fichiers de données ressemblent (il y a 100s de fichiers et de colonnes, mais ici montrant que les colonnes que je suis intéressé par):

First Data File 
    StudentID Grade  
    3   A 
    2   B 
    1   A 

    Second Data File 
    StudentID Grade 
    1   B 
    2   A 
    3   A 

    Third Data File 
    StudentID Grade 
    2   C 
    1   B 
    3   A 

    and so on .... 
    At the end the output should be like: 

    Grade  A B C 
    StudentID 
    1   1 2 0 
    2   1 1 1 
    3   3 0 0 

Mon programme python ressemble à (retirer les importations en provenance de la partie supérieure du fichier)

.....

fields = ['StudentID', 'Grade'] 
path= 'C:/script_testing/' 
i=0 

for filename in glob.glob('C:/script_testing/**/*.txt', recursive=True): 
    temp = pd.read_csv(filename, sep=',', usecols=fields) 
    table1 = pd.crosstab(temp.StudentID, temp.Grade) 
    # Note the if condition is executed only once to initlialize table3 
    if(i==0): 
     table3 = table1 
     i = i + 1 
    table3 = table3 + table1 

writer = pd.ExcelWriter('Report.xlsx', engine='xlsxwriter') 
table3.to_excel(writer, sheet_name='StudentID_vs_Grade') 
writer.save() 

Répondre

1
pd.concat([df1, df2, df3]).pipe(lambda d: pd.crosstab(d.StudentID, d.Grade)) 

Grade  A B C 
StudentID   
1   1 2 0 
2   1 1 1 
3   3 0 0 

Ma tentative de traduction de votre code

fields = ['StudentID', 'Grade'] 
path= 'C:/script_testing/' 
i=0 

parse = lambda f: pd.read_csv(f, usecols=fields) 
table3 = pd.concat(
    [parse(f) for f in glob.glob('C:/script_testing/**/*.txt', recursive=True)] 
).pipe(lambda d: pd.crosstab(d.StudentID, d.Grade)) 

writer = pd.ExcelWriter('Report.xlsx', engine='xlsxwriter') 
table3.to_excel(writer, sheet_name='StudentID_vs_Grade') 
writer.save() 
+0

Merci beaucoup! Ça a marché. Une question de suivi s'il vous plaît. Existe-t-il un moyen d'exclure certains fichiers lors de la lecture de glob.gob()? Par exemple, je veux lire tous les fichiers avec les noms de fichiers Data *, txt mais exclure les fichiers qui ont Data * Old.txt? –

+0

De rien. C'est une question 'glob'. ou vous pourriez faire quelque chose comme '[parse (f) pour f dans glob.glob ('C:/script_testing/**/Data * .txt', recursive = True) sinon 'DataOld' dans f]' – piRSquared