У меня есть CSV-файл, который имеет первую строку в качестве имен столбцов.

Я пытаюсь сгенерировать новый CSV-файл из старого.

Новый CSV-файл получается путем фильтрации исходного CSV-файла по второму столбцу, значение которого является HR

Вот код

import csv
import os
Filename = os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\\Desktop\RosterUnified.csv"
Filename1=os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\\Desktop\RosterCurrentMonth.csv"
f1=open(Filename,'r',newline='\n')
f2=open(Filename1,'w',newline='\n')
reader = csv.DictReader(f1)
writer = csv.writer(f2)
rows = [row for row in reader if row[1] == 'HR']
for row in rows:
    writer.writerow(row)
f1.close()
f2.close()

Я получаю ошибку:

Traceback (most recent call last):
  File "C:\Users\dasa17\Desktop\testcsv.py", line 9, in <module>
    rows = [row for row in reader if row[1] == 'HR']
  File "C:\Users\dasa17\Desktop\testcsv.py", line 9, in <listcomp>
    rows = [row for row in reader if row[1] == 'HR']
KeyError: 1

Образец из CSV-файла, сдвиги B, WO и т. Д. Соответствуют датам

Manager NT ID    Vertical Org   Employee ID 12/1/2016   12/2/2016   12/3/2016   12/4/2016   12/5/2016

johnyv  GS Finance  banakv  B   B   WO  WO  B
johnyv  GS Finance  anbazh  B   B   WO  WO  B
johnyv  GS Finance  immana  B   B   WO  WO  B
immana  GS Finance  raosha  B   B   WO  WO  B
chinj   GS Finance  johnyv  B   B   WO  WO  B
johnyv  GS Finance  yeddub  B   B   WO  WO  B
johnyv  GS Finance  sharmr25    B   B   WO  WO  B
chinj   GS Finance  pellan      B   WO  WO  B
johnyv  GS Finance  ccl B   B   WO  WO  B
johnyv  GS Finance  raos27  B   B   WO  WO  B
johnyv  GS Finance  chinns3 B   B   WO  WO  B
gopals5 IT  guntuv1 B   B   WO  WO  B
goganp  IT  vasuds2 G   G   WO  WO  G
sharmr1 IT  konakr  G   G   C   C   WO
mangan  IT  kanumr  B   B   WO  WO  B
singho1 IT  nanjad  G   G   G   G   G
goganp  IT  tandok  G   G   WO  WO  G
sharmr1 IT  ranjas2 D   WO  A   A   B
mangan  IT  poddar2 A   A   A   A   A
wongs2  IT  subras24    G   G   WO  WO  G
singho1 IT  sevakm  G   G   G   G   G
sharmr1 IT  gopalh  B   B   WO  WO  A
mangan  IT  ramakp2 B   B   B   B   B
cohna1  IT  perumk  B   B   WO  WO  B
ramosj6 IT  maddib  G   G   WO  WO  G
singho1 IT  guptar29    G   G   G   G   G
darisr  IT  vasudl  G   G   WO  WO  G
thangk  IT  singhs70    L   L   WO  WO  L
subras16    IT  hampas  A   A   A   A   A
gordos7 IT  subras16    B   B   B   B   B
omahoc  IT  royd1   G   G   WO  WO  G
darisr  IT  gandhn5 G   G   WO  WO  G
eranhm  IT  arasap  G   G   WO  WO  G
juszkw  IT  patilg2 B   B   WO  WO  B
mkulkarn    IT  kembhp  G   G   WO  WO  G
chavvp  IT  pinnas1 G   G   WO  WO  G
subras16    IT  dhanam  A   A   A   A   A
vasudl  IT  saralm  A   A   A   WO  A
mkulkarn    IT  sukumk1 G   B   WO  WO  B
arorag  IT  sreedr  G   G   WO  WO  G
subras16    IT  sivasm2 B   B   B   B   B
parvar  IT  razdak  B   B   WO  WO  L
vasudl  IT  jayacs1 B   B   WO  WO  A
palang1 IT  vedagm  B   B   B   B   B
mkulkarn    IT  kur5    G   G   WO  WO  G
sharmr1 IT  sambaa1 A   D   WO  WO  B
chavvp  IT  rangak3 G   G   WO  WO  G
arorag  IT  suryaa1 G   G   WO  WO  G
subras16    IT  kumarr27    B   B   B   B   B
Royd1   IT  gavria  G   G   WO  WO  G

Файл был создан с использованием кода

d=open(Filename, 'w',newline='\n') #Format for CSV  input
    c = csv.writer(d)
    c.writerow(["Manager NT ID"," Vertical Org","Employee ID" ]+ dayssl)# Write  the  header list of strings  in the  first row
    for row in result_IT:
        c.writerow(row)#Write output for IT to csv
    d.close()


    e=open(Filename, 'a',newline='\n')

    f= csv.writer(e)
    for row in result_Others:
        f.writerow(row)# Append to the  existing  CSV file with non IT data 
    e.close()
    #Close the  CSV  file
-1
ananda 12 Дек 2016 в 19:53

3 ответа

Лучший ответ

Я не могу понять, почему вы используете DictReader. Вы пытаетесь получить доступ ко второму столбцу, поэтому вам нужно будет использовать что-то вроде row['NT'], то есть вы получите доступ к нему, используя имя заголовка, а не его позицию. Используя стандартный CSV-ридер, вы можете просто использовать позицию.

Я бы порекомендовал вам использовать оператор with Python для доступа к файлам, который обеспечивает автоматическое закрытие файла впоследствии (нет необходимости в выражении close()). Вы также можете использовать os.path.join() чтобы добавить ваши компоненты пути вместе следующим образом:

import os
import csv

input_filename = os.path.join(os.getenv("HOMEDRIVE"), os.getenv("HOMEPATH"), r"Desktop\RosterUnified.csv")
output_filename = os.path.join(os.getenv("HOMEDRIVE"), os.getenv("HOMEPATH"), r"Desktop\RosterCurrentMonth.csv")

with open(input_filename, newline='\n') as f_input, open(output_filename, 'w', newline='\n') as f_output:
    csv_input = csv.reader(f_input)
    csv_output = csv.writer(f_output)
    #csv_output.writerow(next(csv_input))        # optionally copy over the header

    for row in csv_input:
        if row[1] == 'HR':
            csv_output.writerow(row)

Это приведет к выходному файлу CSV, содержащему только строки с HR во втором столбце. Если вам также нужен заголовок, просто раскомментируйте строку.

Работая со строкой за раз, он будет работать с любым размером файла, избегая одновременной загрузки всего файла в память.

1
Martin Evans 12 Дек 2016 в 18:37

О KeyError:

По сути, исключение произошло, потому что Python считает, что вы пытаетесь получить доступ к столбцу, названному «1» в последней строке:

reader = csv.DictReader(f1)
writer = csv.writer(f2)
rows = [row for row in reader if row[1] == 'HR']

Это происходит потому, что вы используете DictReader и, согласно вашему фрагменту CSV, разрешенные столбцы - это столбцы, которые появляются в первой строке вашего файла CSV.

Если возможно, я настоятельно рекомендую вам использовать ";" или "," как разделитель столбцов, чтобы сделать вещи проще

0
Jeanderson Candido 12 Дек 2016 в 17:27

Если у вас есть веская причина не делать этого, просто используйте панд:

import pandas as pd

filename_1 = os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\\Desktop\RosterUnified.csv"
filename_2 = os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\\Desktop\RosterCurrentMonth.csv"

df_1 = pd.read_csv(filename_1, sep='\t', skip_blank_lines=True)
df_2 = df_1[df_1['NT'] == 'HR']

df_2.to_csv(filename_2, sep='\t', index=False)

Если filename_1 отделяется пробелами вместо знаков табуляции, передайте sep=' *' вместо sep='\t' в read_csv.

0
ostrokach 12 Дек 2016 в 17:23