J'essaie d'analyser un fichier csv et d'extraire les données de colonnes spécifiques.
Exemple csv:
ID | Name | Address | City | State | Zip | Phone | OPEID | IPEDS |
10 | C... | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
J'essaie de ne capturer que des colonnes spécifiques, par exemple ID
, Name
, Zip
et Phone
.
Le code que j'ai consulté m'a amené à croire que je peux appeler la colonne spécifique par son numéro correspondant. Ainsi: Name
correspondrait à 2
et une itération dans chaque ligne à l'aide de row[2]
générerait tous les éléments de la colonne 2. Seulement t.
Voici ce que j'ai fait jusqu'à présent:
import sys, argparse, csv
from settings import *
# command arguments
parser = argparse.ArgumentParser(description='csv to postgres',\
fromfile_prefix_chars="@" )
parser.add_argument('file', help='csv file to import', action='store')
args = parser.parse_args()
csv_file = args.file
# open csv file
with open(csv_file, 'rb') as csvfile:
# get number of columns
for line in csvfile.readlines():
array = line.split(',')
first_item = array[0]
num_columns = len(array)
csvfile.seek(0)
reader = csv.reader(csvfile, delimiter=' ')
included_cols = [1, 2, 6, 7]
for row in reader:
content = list(row[i] for i in included_cols)
print content
et je m'attends à ce que cela n'imprimera que les colonnes spécifiques que je veux pour chaque ligne, sauf que ce n'est pas le cas, je reçois uniquement la dernière colonne.
Si vous n'incluez pas votre instruction print in votre boucle for
, la seule façon d'obtenir la dernière colonne de ce code est de ne pas inclure votre instruction print.
C'est probablement la fin de votre code:
for row in reader:
content = list(row[i] for i in included_cols)
print content
Vous voulez que ce soit ceci:
for row in reader:
content = list(row[i] for i in included_cols)
print content
Maintenant que nous avons couvert votre erreur, je voudrais profiter de cette occasion pour vous présenter le module pandas .
Les pandas sont spectaculaires pour traiter les fichiers csv, et le code suivant suffirait pour lire un csv et enregistrer une colonne entière dans une variable:
import pandas as pd
df = pd.read_csv(csv_file)
saved_column = df.column_name #you can also use df['column_name']
donc si vous voulez enregistrer toutes les informations de votre colonne Names
dans une variable, vous n'avez plus qu'à:
names = df.Names
C'est un excellent module et je vous suggère de l'examiner. Si, pour une raison quelconque, votre instruction print était dans la boucle for
et si elle imprimait toujours la dernière colonne, cela ne devrait pas arriver, mais laissez-moi savoir si ma supposition était fausse. Votre code posté contient beaucoup d'erreurs d'indentation, il était donc difficile de savoir où était supposé se trouver. J'espère que cela a été utile!
import csv
from collections import defaultdict
columns = defaultdict(list) # each value in each column is appended to a list
with open('file.txt') as f:
reader = csv.DictReader(f) # read rows into a dictionary format
for row in reader: # read a row as {column1: value1, column2: value2,...}
for (k,v) in row.items(): # go over each column name and value
columns[k].append(v) # append the value into the appropriate list
# based on column name k
print(columns['name'])
print(columns['phone'])
print(columns['street'])
Avec un fichier comme
name,phone,street
Bob,0893,32 Silly
James,000,400 McHilly
Smithers,4442,23 Looped St.
Sortie
>>>
['Bob', 'James', 'Smithers']
['0893', '000', '4442']
['32 Silly', '400 McHilly', '23 Looped St.']
Ou bien si vous souhaitez une indexation numérique des colonnes:
with open('file.txt') as f:
reader = csv.reader(f)
reader.next()
for row in reader:
for (i,v) in enumerate(row):
columns[i].append(v)
print(columns[0])
>>>
['Bob', 'James', 'Smithers']
Pour changer le déliminateur, ajoutez delimiter=" "
à l’instanciation appropriée, par exemple reader = csv.reader(f,delimiter=" ")
.
Utilisez pandas :
import pandas as pd
my_csv = pd.read_csv(filename)
column = my_csv.column_name
# you can also use my_csv['column_name']
Jeter les colonnes inutiles au moment de l'analyse:
my_filtered_csv = pd.read_csv(filename, usecols=['col1', 'col3', 'col7'])
P.S. Je suis simplement en train d'agréger ce que les autres ont dit d'une manière simple. Les réponses réelles sont tirées de ici et ici .
Avec pandas vous pouvez utiliser read_csv
avec le paramètre usecols
:
df = pd.read_csv(filename, usecols=['col1', 'col3', 'col7'])
Exemple:
import pandas as pd
import io
s = '''
total_bill,tip,sex,smoker,day,time,size
16.99,1.01,Female,No,Sun,Dinner,2
10.34,1.66,Male,No,Sun,Dinner,3
21.01,3.5,Male,No,Sun,Dinner,3
'''
df = pd.read_csv(io.StringIO(s), usecols=['total_bill', 'day', 'size'])
print(df)
total_bill day size
0 16.99 Sun 2
1 10.34 Sun 3
2 21.01 Sun 3
Vous pouvez utiliser numpy.loadtext(filename)
. Par exemple, s'il s'agit de votre base de données .csv
:
ID | Name | Address | City | State | Zip | Phone | OPEID | IPEDS |
10 | Adam | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
10 | Carl | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
10 | Adolf | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
10 | Den | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
Et vous voulez la colonne Name
:
import numpy as np
b=np.loadtxt(r'filepath\name.csv',dtype=str,delimiter='|',skiprows=1,usecols=(1,))
>>> b
array([' Adam ', ' Carl ', ' Adolf ', ' Den '],
dtype='|S7')
Plus facilement, vous pouvez utiliser genfromtext
:
b = np.genfromtxt(r'filepath\name.csv', delimiter='|', names=True,dtype=None)
>>> b['Name']
array([' Adam ', ' Carl ', ' Adolf ', ' Den '],
dtype='|S7')
Contexte: Pour ce type de travail, vous devriez utiliser l'incroyable bibliothèque python petl. Cela vous évitera beaucoup de travail et la frustration potentielle de faire les choses «manuellement» avec le module CSV standard. Selon les informations dont je dispose, les seules personnes qui utilisent encore le module csv sont celles qui n’ont pas encore découvert de meilleurs outils pour travailler avec des données tabulaires (pandas, petl, etc.), ce qui est correct, mais si vous envisagez de travailler avec beaucoup de données votre carrière à partir de sources diverses et étranges, apprendre quelque chose comme petl est l’un des meilleurs investissements que vous puissiez faire. Pour commencer, ne prenez que 30 minutes après l’installation de pip. La documentation est excellente.
Réponse: Supposons que vous ayez la première table dans un fichier csv (vous pouvez aussi charger directement depuis la base de données en utilisant petl). Ensuite, il vous suffira de le charger et de procéder comme suit.
from petl import fromcsv, look, cut, tocsv
#Load the table
table1 = fromcsv('table1.csv')
# Alter the colums
table2 = cut(table1, 'Song_Name','Artist_ID')
#have a quick look to make sure things are ok. Prints a nicely formatted table to your console
print look(table2)
# Save to new file
tocsv(table2, 'new.csv')
import pandas as pd
csv_file = pd.read_csv("file.csv")
column_val_list = csv_file.column_name._ndarray_values
Pour récupérer nom de la colonne , au lieu d’utiliser readlines () better use readline () afin d’éviter la lecture en boucle du fichier complet et son stockage dans le tableau.
with open(csv_file, 'rb') as csvfile:
# get number of columns
line = csvfile.readline()
first_item = line.split(',')
Si vous devez traiter les colonnes séparément, j'aime bien déstructurer les colonnes avec le modèle Zip(*iterable)
(en fait, "décompresser"). Donc, pour votre exemple:
ids, names, zips, phones = Zip(*(
(row[1], row[2], row[6], row[7])
for row in reader
))
Grâce à la manière dont vous pouvez indexer et sous-définir un cadre de données pandas, il est très facile d'extraire une colonne unique d'un fichier csv dans une variable:
myVar = pd.read_csv('YourPath', sep = ",")['ColumnName']
Quelques points à considérer:
L'extrait ci-dessus produira un pandas Series
et non dataframe
. La suggestion de ayhan avec usecols
sera également plus rapide si la vitesse est un problème . Tester les deux approches différentes en utilisant %timeit
sur un fichier csv de 2122 Ko donne 22.8 ms
pour l’approche usecols et 53 ms
pour l’approche suggérée.
Et n'oubliez pas import pandas as pd