3 votes

Python/Pandas : Convertir plusieurs fichiers CSV pour avoir une union et un en-tête ordonné et remplir les données manquantes.

J'ai 36 ans. CSV fichiers dans un dossier qui contiennent un nombre impair de colonnes (le nombre de colonnes varie de 90 à 255 dans chaque fichier). Dans un seul CSV le nombre maximal de lignes est de 300, mais les colonnes peuvent avoir de zéro à 300 lignes. Un exemple de fichier CSV est le suivant :

Row  col1 col2 col3 ........................ col200
 1     2      3   4   ......................... 25
 2     1          8   .......................... 0.2
 3     5          2   ........................... 5
 .     .          .   ..........................  .
 .     .          .   ........................... .
 .     .          .   ........................... .
 .     .          .   ........................... .
 .     .          .   ........................... .
 .     .          .   ........................... .
 300   3          12   ..........................  1 

Je veux convertir ces CSV pour obtenir les propriétés suivantes en utilisant Python :

  1. Tous les convertis CSV Les fichiers doivent avoir les mêmes colonnes (même ordre et même taille). Les colonnes sont l'union des colonnes (non répétées) dans tous les fichiers originaux de la CSV des fichiers.

  2. Les colonnes du tableau converti CSV doivent être dans l'ordre, c'est-à-dire que 3rd column de c1.csv doit être le 3rd column d'autres restants CSV également.

  3. Si l'une des colonnes de l'union est absente de l'original CSV il est converti CSV aura les colonnes manquantes ajoutées avec une valeur par défaut dans les lignes (une valeur fixe dans les 300 lignes).

  4. Si une colonne est présentée à la fois dans les colonnes de l'union et dans une colonne originale CSV fichier :

    (a) Si le nombre de lignes de cette colonne est de 300, copiez-la telle quelle.

    (b) Si le nombre de lignes de cette colonne est inférieur à 300, remplissez les lignes restantes par une moyenne des valeurs disponibles dans cette ligne.

Pour obtenir les propriétés mentionnées ci-dessus, j'ai écrit le code suivant en python :

import pandas as pd
import csv
import glob
import os

path = r'FILE PATH TO ORIGINAL FILES' # file path to original files
all_files = glob.glob(path + "/*.csv")
combined_csv = pd.concat([pd.read_csv(f) for f in all_files]) #To get common columns
master_set =list(combined_csv.columns)

for file in all_files:
    filtered_df = pd.read_csv(file)
    for cols in master_set:
        if(cols in filtered_df):
            if(filtered_df[cols].count()>300): pass
            elif (filtered_df[cols].count()<300):
                total = sum(value for value in filtered_df[cols])
                avg = total/filtered_df[cols].count()
                i = filtered_df[cols].count()
                while i<301:
                    filtered_df.at[i,cols] = avg
                    i+=1
        else:
         filtered_df[cols] = 10

    file_name = os.path.split(file)[-1] #Select individual file (eg. c1.csv)
    file_name_path = os.path.join('FILE PATH TO CONVERTED FILES' + file_name) 
    filtered_df.to_csv(file_name_path)

Après avoir exécuté le code ci-dessus, j'obtiens 36 converties CSV avec un ensemble commun de colonnes. Les lignes des colonnes ajoutées (colonnes qui sont dans les colonnes de l'union mais pas dans les fichiers individuels) sont remplies avec les valeurs par défaut. Cependant, les propriétés suivantes ne sont toujours pas remplies avec le code ci-dessus.

  1. L'ordre des colonnes dans les fichiers nouvellement créés CSV ne correspond pas.
  2. La propriété 4(b) mentionnée ci-dessus n'est pas atteinte, c'est-à-dire que toute colonne d'un fichier original qui est présente dans les colonnes d'union mais qui a moins de 300 valeurs (rangées <300) n'est pas remplie par la valeur interpolée.

Je mettrai à jour/modifierai ma question pour plus de clarté.

Toute aide, s'il vous plaît !

1voto

santobedi Points 150

J'ai résolu mon problème avec l'approche suivante :

import pandas as pd
import csv
import glob
import os

path = r'FILE PATH TO ORIGINAL FILES' # file path to original files
all_files = glob.glob(path + "/*.csv")
combined_csv = pd.concat([pd.read_csv(f) for f in all_files]) #To get common columns
master_set =list(combined_csv.columns)

for file in all_files:
    filtered_df = pd.read_csv(file)
    for cols in master_set:
        if(cols in filtered_df):
            total = 0
            if(filtered_df[cols].count()>300): pass
            elif (filtered_df[cols].count()<300):
                for value in filtered_df[cols]:
                    if(math.isnan(value) == False): 
                        total = total + value
                avg = total/filtered_df[cols].count()
                i = filtered_df[cols].count()
                while i<301:
                    filtered_df.at[i,cols] = avg
                    i+=1
        else:
         filtered_df[cols] = 10

    filtered_df = filtered_df[master_set]     
    file_name = os.path.split(file)[-1] #Select individual file (eg. c1.csv)
    file_name_path = os.path.join('FILE PATH TO CONVERTED FILES' + file_name) 
    filtered_df.to_csv(file_name_path)

Pour réaliser (1), j'ai mis à jour le code avec filtered_df = filtered_df[master_set] . Pour 4(b), j'ai mis à jour le code original comme suit if(math.isnan(value) == False) .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X