2010-05-29 11 views
2

J'ai des problèmes avec le traitement de certains fichiers de données CSV pour un projet. Quelqu'un a suggéré d'utiliser le lecteur python/csv pour aider à décomposer les fichiers, ce que j'ai eu du succès avec, mais pas d'une manière que je puisse utiliser.Écriture de fichiers csv avec python avec des paramètres de formatage précis

Ce code est un peu différent de ce que j'essayais auparavant. Je tente essentiellement de créer un tableau. Dans le format de données brutes, les 7 premières lignes ne contiennent aucune donnée, puis chaque colonne contient 50 expériences, chacune avec 4000 lignes, pour 200 000 lignes au total. Ce que je veux faire est de prendre chaque colonne, et en faire un fichier csv individuel, avec chaque expérience dans sa propre colonne. Ce serait donc un tableau de 50 colonnes et 4000 lignes pour chaque type de données. Le code ici décompose les valeurs correctes, je pense que la logique est correcte, mais elle dégrade le contraire de la façon dont je le veux. Je veux les séparateurs sans guillemets (les virgules et les espaces) et je veux les valeurs de l'élément entre guillemets. En ce moment, c'est exactement le contraire pour les deux, les valeurs d'éléments sans guillemets, et les séparateurs entre guillemets. J'ai passé plusieurs heures à essayer de comprendre comment faire cela en vain,

import csv 

ifile = open('00_follow_maverick.csv') 
epistemicfile = open('00_follower_maverick_EP.csv', 'w') 

reader = csv.reader(ifile) 

colnum = 0 
rownum = 0 
y = 0 
z = 8 
for column in reader: 
    rownum = 4000 * y + z 
    for element in column: 
     writer = csv.writer(epistemicfile) 
     if y <= 50: 
      y = y + 1 
      writer.writerow([element]) 
      writer.writerow(',') 
      rownum = x * y + z 
     if y > 50: 
      y = 0 
      z = z + 1 
      writer.writerow(' ') 
      rownum = x * y + z 
     if z >= 4008: 
      break 

ce qui se passe: Je prends chaque ligne dans le fichier de données brutes dans les itérations de 4000, afin que je puisse séparer les avec des virgules pour les 50 expériences. Lorsque y, l'indicateur d'expérience atteint ici 50, il revient à l'expérience 0 et ajoute 1 à z, ce qui lui indique quelle ligne regarder, par la formule de 4000 * y + z. Quand il complète les lignes pour les 50 expériences, c'est fini. Le problème ici est que je ne sais pas comment obtenir python pour écrire les valeurs réelles entre guillemets, et mes séparateurs en dehors des guillemets.

Toute aide sera très appréciée. Excuses si cela semble une question stupide, je n'ai aucune expérience de programmation, c'est ma première tentative jamais. Je vous remercie. Désolé, je vais essayer de rendre cela plus clair. Le fichier csv d'origine comporte plusieurs colonnes, chacune d'entre elles constituant des ensembles de données différents.

Un exemple miniature du fichier brut ressemble:

column1    column2   column3 
exp1data1time1  exp1data2time1  exp1data3time1 
exp1data1time2  exp1data2time2  exp1data3time2 
exp2data1time1  exp2data2time1  exp2data3time1 
exp2data1time2  exp2data2time2  exp2data3time2 
exp3data1time1  exp3data2time1  exp3data3time1 
exp3data1time2  exp3data2time2  exp3data3time2 

Ainsi, la version actuelle a 4000 lignes au lieu de 2 pour chaque nouvelle expérience. Il y a 40 colonnes dans la version actuelle, mais fondamentalement, le type de données dans le fichier brut correspond au numéro de colonne. Je veux séparer chaque type de données ou colonne dans un fichier csv individuel.

Cela ressemblerait à ceci:

csv file1 

exp1data1time1 exp2data1time1 exp3data1time1 
exp1data1time2 exp2data1time2 exp3data1time2 

csv file2 

exp1data2time1 exp2data2time1 exp3data2time1 
exp1data2time2 exp2data2time2 exp3data2time2 

csv file3 

exp1data3time1 exp2data3time1 exp3data3time1 
exp1data3time2 exp2data3time2 exp3data3time2 

Alors, je déplace les données brutes dans le fichier à une nouvelle colonne, et chaque type de données à son propre fichier. En ce moment je vais faire un seul fichier, jusqu'à ce que je puisse déplacer les expériences séparées pour séparer les colonnes dans le nouveau fichier. Donc, dans le code, ce qui précède ferait le 4000 en 2. J'espère que cela a plus de sens, mais sinon, je vais essayer à nouveau.

+0

Je pense que nous allons avoir du mal à suivre cela. Afficher l'entrée et la sortie désirée. –

+0

Je suggère que nous apprenions à M. Harrison «à pêcher» ou lui indiquions «comment pêcher» plutôt que «lui donner un poisson». Ce code n'est pas son problème principal. – msw

Répondre

2

Si j'avais un chat pour chaque fois que je voyais une base de données bio ou Psych ou chem dans cet état:

« chaque colonne contient 50 expériences, chacune avec 4000 lignes, pour 200000 quelques lignes au total Ce que je veux faire est de prendre chaque colonne, et en faire un fichier csv individuel, avec chaque expérience dans sa propre colonne .Il serait donc un tableau de 50 colonnes et 4000 lignes pour chaque donnée de type »

Je serais trop farking beaucoup de chats.

Je ne regardais pas même à votre code parce que la re-mangling que vous proposez est juste un autre problème qui devra être résolu.Je ne vous blâme pas, vous prétendez être un novice et tous vos pairs font le même genre d'erreur.Les programmeurs débutants qui doivent encore comprendre comment utiliser des tableaux se terminent souvent avec des déclarations variables comme:

integer response01, response02, response03, response04, ... 

puis très, très redondant code quand ils essaient de voir si chaque réponse est - disons - 1. Je pense que c'est une erreur si séduisante en bio-informatique, car il modélise réellement les notations de papier dont ils viennent plutôt bien. Malheureusement, le modèle de feuille de papier n'est pas la meilleure façon de modéliser les données.

Vous devriez lire et comprendre pourquoi database normalization a été développé, codifié et a fini par dominer la façon dont les gens pensent des données structurées. Un article de Wikipédia peut ne pas suffire. En utilisant l'exemple que j'ai extrait, laissez-moi essayer d'expliquer comment je pense à cela. Vos données consistent en des observations; dans l'autre sens, la donnée primaire est une observation singulière. Cette observation a cependant un contexte: elle fait partie d'un ensemble de 4000 observations, où chaque ensemble appartient à l'une des 50 expériences. Si vous deviez joindre un contexte à chaque observation que vous auriez du vent avec un système d'adressage qui ressemble à:

<experiment_number, observation_number, value> 

Dans le jargon de base de données, qui est un tuple, et il est capable de représenter, sans ambiguïté et parfait symétrie l'intégralité de vos données. Je ne suis pas certain que je l'ai compris la structure exacte de vos données, donc peut-être quelque chose de plus comme:

<experiment_number, protocol_number, observation_number, value> 

où le protocole peut être une forme de type variable de traitement - disons pH. Mais notez que je n'ai pas appelé le protocole un pH et je ne l'enregistre pas comme tel dans la base de données. Ce dont j'ai alors besoin est un tableau auxiliaire montrant les paramètres pertinents du protocole, par exemple.:

<protocol_number, acidity, temperature, pressure> 

Maintenant, nous venons construit une « relation » que ces gens de la base de données aiment parler; nous avons également commencé à normaliser les données. Si vous avez besoin de connaître le pH pour un protocole donné, il y a un et un seul endroit pour le trouver, dans la rangée appropriée de la table de protocole. Notez que j'ai divorcé les données qui correspondent si bien ensemble sur une feuille de données et de la table d'observation je ne peux pas voir le pH pour une donnée donnée. Mais ce n'est pas grave, parce que je peux juste le chercher dans ma table de protocole si nécessaire. C'est une "jointure relationnelle" et si j'en avais besoin, je pourrais fusionner tous les différents paramètres de toutes les différentes tables et reconstituer la feuille de données originale dans sa gloire originale et non structurée.

J'espère que cette réponse vous sera utile. Je suis certain que je ne sais même pas de quel domaine proviennent vos données, mais ces principes s'appliquent à tous les domaines, des essais de médicaments au traitement des demandes d'achat. S'il vous plaît comprenez que j'essaie d'informer, à votre demande, et il n'y a aucune condescendance prévue. J'accueille d'autres questions à ce sujet.

+0

Très bien, malheureusement, je ne sais pas comment attacher des informations de contexte aux données non plus. Les principes s'appliquent probablement, je pense que je comprends ce que vous voulez dire. À plus long terme, je pourrais voir pourquoi cela serait utile, mais j'ai toujours travaillé avec des choses comme je l'ai décrit. Je suis curieux de savoir quel est le problème si ce n'est pas le code? Cela fonctionne pour ce que nous faisons, même si ce n'est pas de la meilleure façon. Le département est la philosophie. L'analyse des données expérimentales est très controversée dans mon département, généralement pas une méthode approuvée, et donc pas enseignée. Je garderai un oeil sur ça. Je vous remercie. –

+0

+1 pour une réponse qui prouve que cette affirmation est fausse: «Ceci est un site de questions et réponses, pas une question complexe, une réponse perspicace qui vous pousse à devenir un site personnel. Les gens devraient être capables de poser des questions simples avec des réponses simples, qui peuvent tout simplement être nourries à la cuillère, beaucoup de gens veulent juste écrire du code qui fonctionne. -Owen (http://meta.stackexchange.com/questions/8724/how-to-deal-with-google-questions/8728#8728) – bernie

+0

@Adam: merci pour les gentils mots, je ne suis pas certain que Je devrais dire "oups" pour avoir violé la méta. *;) @Ben: merci pour la clarification, je dois dire que "l'épistémologie expérimentale" était une nouvelle idée pour moi (et apparemment pour la philosophie). Après avoir fait quelques lectures sur le sujet, il s'agit vraiment d'appliquer des méthodes sociologiques ou anthropologiques à des questions philosophiques. En tant que sous-domaine relativement nouveau essayant de s'établir dans le canon, il me semble que vous devriez utiliser les meilleures pratiques analytiques développées au cours du siècle dernier, pas confondre avec les erreurs les plus fréquentes des novices. – msw

0

Normalisation de l'ensemble de données

Merci d'avoir donné l'exemple. Vous avez déjà le contexte que j'ai décrit, peut-être que je peux le rendre plus clair.

column1    column2   column3 
exp1data1time1  exp1data2time1  exp1data3time1 
exp1data1time2  exp1data2time2  exp1data3time2 

Les colonnes sont un artifice fabriqué par le dernier type; c'est-à-dire qu'ils ne portent aucune information pertinente. Si on analyse une forme normale, vos données ressemble mon premier tuple proposé:

<experiment_number, time, response_number, response> 

où je soupçonne time peut vouloir dire en fait « id_sujet » ou « trial_number ». Il peut très bien vous sembler incongru de joindre toutes les différentes valeurs response dans le même jeu de données; En effet, basé sur votre sortie désirée, je pense que c'est le cas. À première vue, l'objection «mais la réponse du sujet à une question sur les propriétés épistémiques des chaises n'a aucun lien avec leurs croyances méta-épistémiques concernant la couleur», mais ce serait une erreur. Les données sont liées parce qu'elles ont un sujet expérimental commun, et l'auto-corrélation est un concept important dans l'analyse sociologique. Par exemple, vous pouvez trouver que le répondant A donne les mêmes réponses que le répondant B, sauf que toutes les réponses de A sont biaisées d'autant plus que le sujet a compris les critères. Cela ferait une différence très réelle dans les valeurs absolues des données, mais j'espère que vous pouvez voir que la question «A et B ont effectivement différents modèles épistémiques? est saillant et valide. Une méthode de modélisation des données permet de répondre facilement à cette question, ce qui n'est pas le cas de la méthode souhaitée.

Code d'analyse syntaxique à suivre sous peu.

0

Le code normalisant

#!/usr/bin/python 

"""parses a csv file containing a particular data layout and normalizes 

    The raw data set is a csv file of the form:: 

     column1    column2    column3 
     exp01data01time01  exp01data02time01  exp01data03time01 
     exp01data01time02  exp01data02time02  exp01data03time02 

    where there are 40 such columns and the literal column title 
    is added as context to the output row 

    it is assumed that the columns are comma separated but 
    the lexical form of the subcolumns is unspecified. 

    Output will consist of a single CSV output stream 
    on stdout of the form:: 

     exp01, time01, data01, column1 

    for varying actual values of each field. 
""" 

import csv 
import sys 

def split_subfields(s): 
    """returns a list of subfields of s 
     this function is expected to be re-written to match the actual, 
     unspecified lexical structure of s.""" 
    return [s[0:5], s[5:11], s[11:17]] 


def normalise_data(reader, writer): 
    """returns a list of the column headings from the reader""" 

    # obtain the headings for use in normalization 
    names = reader.next() 

    # get the data rows, split them out by column, add the column name 
    for row in reader: 
     for column, datum in enumerate(row): 
      fields = split_subfields(datum) 
      fields.append(names[column]) 
      writer.writerow(fields) 

def main(): 
    if len(sys.argv) != 2: 
     print >> sys.stderr, ('usage: %s input.csv' % sys.argv[0]) 
     sys.exit(1) 

    in_file = sys.argv[1] 

    reader = csv.reader(open(in_file)) 
    writer = csv.writer(sys.stdout) 
    normalise_data(reader, writer) 

if __name__ == '__main__': main() 

telle que la commande python epistem.py raw_data.csv > cooked_data.csv donne la sortie extrairez ressemblant à:

exp01,data01,time01,column1 
... 
exp01,data40,time01,column40 
exp01,data01,time02,column1 
exp01,data01,time03,column1 
... 
exp02,data40,time15,column40 
+0

Merci. Je vais regarder l'arrangement de données. Mon professeur qui dirige cette chose s'en fout, il préfèrerait voir les graphiques qui en résultent, etc. Il y a un deuxième professeur (de sociologie) qui a eu une certaine implication de temps en temps, alors je vais le faire fonctionner par lui. Voyez comment il aurait voulu les données s'il les analysait. L'exp est en fait sur l'acquisition de connaissances, plutôt que sur le traitement/les croyances, de sorte que les valeurs sont à des moments différents. Pour voir la quantité de temps à réaliser. Enfin, le coeur de la question. Nous essayons d'utiliser des données réelles pour construire des modèles informatiques d'acquisition de connaissances. –

+0

Donc, cet ensemble de données provient uniquement du modèle informatique, et les modèles épistémiques y sont déjà spécifiquement pris en compte. D'accord, merci, g'day –