Python之CSV模塊


1. CSV簡介

       CSV(Comma Separated Values)是逗號分隔符文本格式,常用於Excel和數據庫的導入和導出,Python標准庫的CSV模塊提供了讀取和寫入CSV格式文件的對象。

1.1 csv.reader對象和csv文件的讀取

      csv.reader(csvfile,dialect='excel',**fmtparams),主要用於文件的讀取,返回一個reader對象用於在csv文件內容上進行行迭代。

     參數csvfile是文件對象或者list對象;dialect 用於指定csv的格式模式不同程序輸出的csv格式有細微差別;fmtparams是一系列參數列表,主要用於設置特定的格式,以覆蓋dialect中的格式。

      csv.reader對象是可迭代對象,包含以下屬性:

  1. csv.reader().dialect    #返回其dialect
  2. csv.reader().line_num   #f返回讀入的行數

        示例1:使用reader對象讀取csv文件scores.csv,文件內容如下:

  學號,姓名,性別,班級,語文,數學,英語
  100001,小雨,女,1班,72,85,87
  100002,小雪,女,2班,67,87,77
  100003,小宇,男,3班,88,78,78
  100004,小天,男,1班,76,87,84
  100005,小軍,男,3班,79,86,83

#_*_coding=utf-8
import csv
def readcsv(csvfilepath):#列表方式讀取
    with open(csvfilepath, 'r', newline='',encoding='utf-8') as csvfile:
        reader = csv.reader(csvfile)#創建csv.reader對象
        for row in reader:
            # 讀取出的內容是列表格式的
            print(row)
        print(reader.line_num)
if __name__=='__main__':
    readcsv(r'E:\2018-12-19\scores.csv')
    #輸出
    # ['學號', '姓名', '性別', '班級', '語文', '數學', '英語']
    # ['100001', '小雨', '女', '1班', '72', '85', '87']
    # ['100002', '小雪', '女', '2班', '67', '87', '77']
    #....(略)
    # 6
reader對象

 1.2 csv.writer對象和csv文件的寫入

  csv.writer(csvfile,dialect='excel',**fmtparams),主要用於把列表數據寫入到csv文件。

  其中參數csvfile是任何支持write()方法的對象,通常為文件對象;dialect 和fmtparams與csv.reader對象構造函數中的參數意義相同。

  csv.writer對象包含以下屬性和方法:

  1. writer.writerow(row)          #方法,寫入一行數據
  2. writer.writerows                     #方法,寫入多行數據
  3. writer.dialect                     #只讀屬性,返回其dialect

  示例2:  使用writer對象寫入csv文件

import csv
def writecsv(csvfilepath):#列表方式寫入
    rows=[(100006,'小江','','1班','77','79','80'),(100007,'小美','','4班','77','88','80')]
    with open(csvfilepath,'a+',newline='')as csvfile:
        writer = csv.writer(csvfile,dialect='excel')
        writer.writerows(rows)#寫入多行
        print(writer.dialect)


if __name__=='__main__':
   
    writecsv(r'E:\2018-12-19\scores.csv')
writer對象

 1.3 csv.DictReader對象和csv文件的讀取

  使用csv.reader對象從csv文件讀取數據,結果為列表對象row,需要通過索引row[i]訪問。如果希望通過csv文件的首行標題字段名訪問,則可以使用csv.DictReader對象讀取。

       csv.DictReader(csvfile,fieldnames=None,restkey=None,restval=None,dialect='excel',*args,**kwds)

  其中,csvfile是文件對象或list對象;fieldnames用於指定字段名,如果沒有指定,則第一行為字段名;restkey和restval用於指定字段名和數據個數不一致時所對應的字段名或數據值,其他參數同reader對象。

  DictReader對象屬性和方法: 

  # 方法:
  csv.DictReader().__next__()# 稱之為next(reader)
  # 屬性:
  csvreader.dialect          # 解析器使用的方言的只讀描述。
  csvreader.line_num      #返回讀入的行數
  csvreader.fieldnames   #返回標題字段名

  示例3 :使用DictReader對象讀取csv文件

import csv
def  readcsv2(csvfilepath):
    with open(csvfilepath,newline='') as f:
        f_csv = csv.DictReader(f)
        for row in f_csv:
            print(row['姓名'],row['班級'])
        # print('fieldnames:',f_csv.fieldnames)
        # print('dialect:',f_csv.dialect)
        # print('line_num:',f_csv.line_num)

if __name__=='__main__':
    readcsv2(r'E:\2018-12-19\scores.csv')
DictReader對象

 1.4 csv.DictWriter對象和csv文件的寫入

  csv.DictWriter(csvfile,fieldnames,restval = '',extrasaction = 'raise',dialect = 'excel',*args,**kwds)

   extrasaction用於指定多余字段時的操作,其他參數同上。

  DictWriter對象的屬性和方法:

       # 方法:
  csvwriter.writerow(row)               # 將row寫入writer的文件對象,根據當前方言進行格式化。支持迭代
  csvwriter.writerows(rows)           # 將行中的所有元素寫入編寫器的文件對象,並根據當前方言進行格式化。支持迭代
  DictWriter.writeheader()              # 寫入標題字段名
  # 屬性:
  csvwriter.dialect # 使用的方言只讀描述
  示例4 :使用DictWriter對象寫入csv文件

import csv
def writecsv2(csvfilepath):
    headers = ['學號','姓名','性別','班級','語文','數學','英語']
    rows = [{'學號':'100001','姓名':'小魚','性別':'','班級':'1班','語文':'72','數學':'82','英語':'85'},
            {'學號':'100002','姓名':'小高','性別':'','班級':'6班','語文': '74', '數學': '88', '英語': '85'}
            ]
    with open(csvfilepath,'a+',newline='') as f:
        f_csv = csv.DictWriter(f,headers)
        f_csv.writerows(rows)
if __name__=='__main__':
    
   writecsv2(r'E:\2018-12-19\scores.csv')
DictWriter對象

 1.5 csv文件格式化參數和Dialect對象

  1.5.1 csv 文件格式化參數

  創建reader/writer對象時,可以指定csv文件格式化命名參數。

  參數說明:
  delimiter  用於分隔字段的分隔符。默認為","
  lineterminator  用於寫操作的行結束符,默認為“'\r\n ' 。讀操作將忽略此選項,它能認出跨平台的行結束符
  quotechar  用於帶有特殊字符(如分隔符)的字段的引用符號。默認為' " '
  quoting  引用約定。可選值包括

      csv.QUOTE _ ALL (引用用所有字段)
      csv.QUOTE_MINIMAL(引用如分隔符之類特殊字符的字段)默認
      csv.QUOTE_NONNUMERIC (非數字字段)
      csv.QUOTE_NON (不引用)
  skipinitialspace  忽略分隔符后面的空白符。默認為False
  doublequote  如何處理字段內的引用符號。如果為True ,字符串中的雙引號使用" "表示;如果為False,使用轉義字符escapechar指定的字符
  escapechar 用於對分隔符進行轉義的字符串

  strict 如果為True,讀入錯誤格式的CSV行時將導致csv.Error;默認值為False

  示例5 :csv文件格式化參數示例

import csv
def writecsv3(csvfilepath):
    headers = ['學號','姓名','性別','班級','語文','數學','英語']
    rows = [{'學號':'100010','姓名':'小南','性別':'','班級':'1班','語文':'70','數學':'89','英語':'85'},
            {'學號':'100011','姓名':'小風','性別':'','班級':'6班','語文': '79', '數學': '89', '英語': '85'}
            ]
    with open(csvfilepath,'a+',newline='') as f:
        f_csv = csv.DictWriter(f,headers,delimiter = '',quoting = csv.QUOTE_ALL)
        f_csv.writerows(rows)
if __name__=='__main__':
   
   writecsv3(r'E:\2018-12-19\scores.csv')
csv文件格式化

  1.5.2 Dialect 對象

  若干格式化參數可以組成Dialect對象,Dialect對象包含對應於命名格式化參數的屬性。可以創建 Dialect或其派生類的對象,然后傳遞給reader或writer的構造函數

  可以使用下列csv模塊的函數,創建Dialect對象。

  csv.register_dialect(name[,dialect],**fmtparams):使用命名參數,注冊一個名稱。

  csv.unregister_dialect(name):取消注冊的名稱。

  csv.get_dialect(name):獲取注冊的名稱的Dialect對象,無注冊時csv.Error。

  csv.list_dialects():所有注冊Dialect對象的列表。

       另外可以使用csv模塊函數,獲取和設置字段的長度限制:csv.filed_size_limit([new_linit])

  示例6:Dialect對象示例

import csv
def writecsv4(csvfilepath):
    csv.register_dialect('mydialect',delimiter = '*',quoting = csv.QUOTE_ALL)
    headers = ['學號','姓名','性別','班級','語文','數學','英語']
    rows = [{'學號':'100013','姓名':'小北','性別':'','班級':'1班','語文':'70','數學':'80','英語':'85'},
            {'學號':'100014','姓名':'小琴','性別':'','班級':'6班','語文': '77', '數學': '89', '英語': '85'}
            ]
    with open(csvfilepath,'a+',newline='') as f:
        f_csv = csv.DictWriter(f,headers,dialect='mydialect')
        f_csv.writerows(rows)
if __name__=='__main__':
   
   writecsv4(r'E:\2018-12-19\scores.csv')
dialect對象

 2. 使用pandas處理大型csv文件

 2.1 pandas簡介

Pandas 即Python Data Analysis Library,是為了解決數據分析而創建的第三方工具,它不僅提供了豐富的數據模型,而且支持多種文件格式處理,包括CSV、HDF5、HTML 等,能夠提供高效的大型數據處理。其支持的兩種數據結構——Series 和DataFrame——是數據處
理的基礎。下面先來介紹這兩種數據結構。
Series:它是一種類似數組的帶索引的一維數據結構,支持的類型與NumPy兼容。如果不指定索引,默認為0到N-1。通過obj.values() 和obj.index() 可以分別獲取值和索引。當給Series 傳遞一個字典的時候,Series 的索引將根據字典中的鍵排序。如果傳入字典的時候同時重新指定了index 參數,當index 與字典中的鍵不匹配的時候,會出現時數據丟失的情況,標記為NaN。在pandas 中用函數isnull() 和notnull() 來檢測數據是否丟失。
import pandas

>>> obj1 = Series([1, 'a', (1,2), 3], index=['a', 'b', 'c', 'd'])
>>> obj1#value 和index 一一匹配
a 1
b a
c (1, 2)
d 3
dtype: object
>>> obj2=Series({"Book":"Python","Author":"Dan","ISBN":"011334","Price":25},index=['book','Author','ISBM','Price'])
>>> obj2.isnull()
book True # 指定的index 與字典的鍵不匹配,發生數據丟失
Author False
ISBM True # 指定的index 與字典的鍵不匹配,發生數據丟失
Price False
dtype: bool
View Code
DataFrame :類似於電子表格,其數據為排好序的數據列的集合,每一列都可以是不同的數據類型,它類似於一個二維數據結構,支持行和列的索引。和Series 一樣,索引會自動分配並且能根據指定的列進行排序。使用最多的方式是通過一個長度相等的列表的字典來構建。構建一個DataFrame 最常用的方式是用一個相等長度 列表的字典或NumPy 數組。DataFrame 也可以通過columns 指定序列的順序進行排序。
data = {'OrderDate': ['1-6-10', '1-23-10', '2-9-10', '2-26-10', '3-15-10'],
... 'Region': ['East', 'Central', 'Central', 'West', 'East'],
... 'Rep': ['Jones', 'Kivell', 'Jardine', 'Gill', 'Sorv ino']}
>>>
>>> DataFrame(data,columns=['OrderDate','Region','Rep'])# 通過字典構建,按照cloumns指定的順序排序
OrderDate Region Rep
0 1-6-10 East Jones
1 1-23-10 Central Kivell
2 2-9-10 Central Jardine
3 2-26-10 West Gill
4 3-15-10 East Sorvino
View Code
2.2 pandas處理csv文件

Pandas中處理CSV文件的函數主要為read_csv()和to_csv()這兩個,其中read_csv()讀取CSV文件的內容並返回DataFrame,to_csv() 則是其逆過程。
1)讀取指定行和列的數據
具體的實現代碼如下: df = pd.read_csv("SampleData.csv",nrows=5,usecols=['OrderDate','Item','Total']) 方法read_csv()的參數nrows 指定讀取文件的行數,usecols 指定所要讀取的列的列名,如果沒有列名,可直接使用索引0、1、...、n-1。上述兩個參數對大文件處理非常有用,可以避免讀入整個文件而只選取所需要部分進行讀取。
import pandas as pd def readcsv3(csvfilepath): df = pd.read_csv(csvfilepath, nrows=3, usecols=['學號', '姓名','班級'],encoding='gbk') print(df) if __name__=='__main__': readcsv3(r'E:\2018-12-19\scores.csv') #輸出 
   # 學號 姓名 班級
   # 0 100001 小雨 1班
   # 1 100002 小雪 2班
   # 2 100003 小宇 3班
讀取指定行和列

如果出現錯誤提示:UnicodeDecodeError: 'ascii' codec can't decode byte 0xb8

原因:含有中文字符,將encoding設置為gbk

2)設置CSV文件與excel兼容
將scores.csv文件內容修改如下:
學號,姓名,性別,班級,語文,數學,英語
100001,小雨,女,1班,72,85,87
100002,小雪,女,2班,67,87,77
100003,小宇,小白,男,3班,88,78,78
100004,小天,男,1班,76,87,84
100005,小軍,男,3班,79,86,83
100006,小江,男,1班,77,79,80,44
100007,小美,女,4班,77,88,80,44
100001,小魚,男,1班,72,82,85,33
100002,小高,女,6班,74,88,85,77
Scores.csv
下面的代碼用於設置CSV 文件與excel 兼容,error_bad_lines=False 會直接忽略不符合要求的記錄。
import pandas as pd
def  readcsv4(csvfilepath):
    dia = csv.excel()
    df = pd.read_csv(csvfilepath, dialect=dia, error_bad_lines=False,encoding='gbk')
    print(df)

if __name__=='__main__':
    readcsv4(r'E:\2018-12-19\scores.csv')
   #輸出
   #      學號  姓名 性別  班級  語文  數學  英語
   # 0  100001  小雨  女   1班   72    85    87
   # 1  100002  小雪  女   2班   67    87    77
   # 2  100004  小天  男  1班    76    87    84
   # 3  100005  小軍  男  3班    79    86    83
View Code
3)對文件進行分塊處理並返回一個可迭代的對象
分塊處理可以避免將所有的文件載入內存,僅在使用的時候讀入所需內容。參數chunksize設置分塊的文件行數,2表示每一塊包含2個記錄。將參數iterator 設置為True時,返回值為TextFileReader,它是一個可迭代對象。
來看下面的例子,當chunksize=2、iterator=True 時,每次輸出為包含2個記錄的塊。
import pandas as pd
def  readcsv5(csvfilepath):
    df = pd.read_csv(csvfilepath,encoding='gbk',chunksize=2,iterator=True)
    print(df)#<pandas.io.parsers.TextFileReader object at 0x00000293FA870320>
    print(iter(df).__next__())

if __name__=='__main__':
    readcsv5(r'E:\2018-12-19\scores.csv')
   #輸出
   #      學號  姓名 性別  班級  語文  數學  英語
   # 0  100001  小雨  女   1班   72    85    87
   # 1  100002  小雪  女   2班   67    87    77
View Code
 
        
>>>>>待續

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM