Python 數據處理(十四)—— IO 工具 CSV示例

2021-03-02 生信學習手冊
Python 數據處理(十四)3 分類類型

分類類型可以通過指定 dtype='category' 或 dtype=CategoricalDtype(categories, ordered) 直接解析

In [31]: data = "col1,col2,col3\na,b,1\na,b,2\nc,d,3"

In [32]: pd.read_csv(StringIO(data))
Out[32]: 
  col1 col2  col3
0    a    b     1
1    a    b     2
2    c    d     3

In [33]: pd.read_csv(StringIO(data)).dtypes
Out[33]: 
col1    object
col2    object
col3     int64
dtype: object

In [34]: pd.read_csv(StringIO(data), dtype="category").dtypes
Out[34]: 
col1    category
col2    category
col3    category
dtype: object

也可以使用字典對指定列設置類型

In [35]: pd.read_csv(StringIO(data), dtype={"col1": "category"}).dtypes
Out[35]: 
col1    category
col2      object
col3       int64
dtype: object

指定 dtype ='category' 將導致無序分類,其類別是數據中所有觀察值的集合。

如果要更好地控制類別和順序,請提前創建 CategoricalDtype,然後將其傳遞給該列的 dtype

In [36]: from pandas.api.types import CategoricalDtype

In [37]: dtype = CategoricalDtype(["d", "c", "b", "a"], ordered=True)

In [38]: pd.read_csv(StringIO(data), dtype={"col1": dtype}).dtypes
Out[38]: 
col1    category
col2      object
col3       int64
dtype: object

使用 dtype=CategoricalDtype 時,超出的數據類型將被視為缺失值

In [39]: dtype = CategoricalDtype(["a", "b", "d"])  # No 'c'

In [40]: pd.read_csv(StringIO(data), dtype={"col1": dtype}).col1
Out[40]: 
0      a
1      a
2    NaN
Name: col1, dtype: category
Categories (3, object): ['a', 'b', 'd']

這與 Categorical.set_categories() 的行為相匹配

注意

當 dtype='category' 時,生成的類別將始終解析為字符串(object 類型)。

如果類別是數字型,則可以使用 to_numeric() 函數或其他轉換器進行轉換,如 to_datetime()當 dtype 是一個同構(所有數字、所有日期時間等)的 CategoricalDtype 時,轉換將自動完成

In [41]: df = pd.read_csv(StringIO(data), dtype="category")

In [42]: df.dtypes
Out[42]: 
col1    category
col2    category
col3    category
dtype: object

In [43]: df["col3"]
Out[43]: 
0    1
1    2
2    3
Name: col3, dtype: category
Categories (3, object): ['1', '2', '3']

In [44]: df["col3"].cat.categories = pd.to_numeric(df["col3"].cat.categories)

In [45]: df["col3"]
Out[45]: 
0    1
1    2
2    3
Name: col3, dtype: category
Categories (3, int64): [1, 2, 3]

❞4 列的命名和使用4.1 處理列名

一個文件可能有也可能沒有標題行,pandas 默認將第一行用作列名

In [46]: data = "a,b,c\n1,2,3\n4,5,6\n7,8,9"

In [47]: print(data)
a,b,c
1,2,3
4,5,6
7,8,9

In [48]: pd.read_csv(StringIO(data))
Out[48]: 
   a  b  c
0  1  2  3
1  4  5  6
2  7  8  9

通過將 names 參數與 header 一起使用

In [49]: print(data)
a,b,c
1,2,3
4,5,6
7,8,9

In [50]: pd.read_csv(StringIO(data), names=["foo", "bar", "baz"], header=0)
Out[50]: 
   foo  bar  baz
0    1    2    3
1    4    5    6
2    7    8    9

In [51]: pd.read_csv(StringIO(data), names=["foo", "bar", "baz"], header=None)
Out[51]: 
  foo bar baz
0   a   b   c
1   1   2   3
2   4   5   6
3   7   8   9

如果標題不在第一行中,可以將行號傳遞給 header,將會跳過前面的行

In [52]: data = "skip this skip it\na,b,c\n1,2,3\n4,5,6\n7,8,9"

In [53]: pd.read_csv(StringIO(data), header=1)
Out[53]: 
   a  b  c
0  1  2  3
1  4  5  6
2  7  8  9

5. 重複列名處理

如果文件或表頭包含重複的名稱,默認情況下 pandas 會將它們區分開,以防止數據覆蓋

In [54]: data = "a,b,a\n0,1,2\n3,4,5"

In [55]: pd.read_csv(StringIO(data))
Out[55]: 
   a  b  a.1
0  0  1    2
1  3  4    5

默認情況下,mangle_dupe_cols=True 會使用 .N 的方式標記重名的列,如果設置 mangle_dupe_cols=False 將會出現重複的列

In [2]: data = 'a,b,a\n0,1,2\n3,4,5'
In [3]: pd.read_csv(StringIO(data), mangle_dupe_cols=False)
Out[3]:
   a  b  a
0  2  1  2
1  5  4  5

為了防止用戶遇到重複數據的問題,現在,如果 mangle_dupe_cols != True,則會引發 ValueError 異常:

In [2]: data = 'a,b,a\n0,1,2\n3,4,5'
In [3]: pd.read_csv(StringIO(data), mangle_dupe_cols=False)
...
ValueError: Setting mangle_dupe_cols=False is not supported yet

5.1 篩選列

usecols 參數允許你選擇文件中指定的列,可以使用列名、位置或一個可調用的函數

In [56]: data = "a,b,c,d\n1,2,3,foo\n4,5,6,bar\n7,8,9,baz"

In [57]: pd.read_csv(StringIO(data))
Out[57]: 
   a  b  c    d
0  1  2  3  foo
1  4  5  6  bar
2  7  8  9  baz

In [58]: pd.read_csv(StringIO(data), usecols=["b", "d"])
Out[58]: 
   b    d
0  2  foo
1  5  bar
2  8  baz

In [59]: pd.read_csv(StringIO(data), usecols=[0, 2, 3])
Out[59]: 
   a  c    d
0  1  3  foo
1  4  6  bar
2  7  9  baz

In [60]: pd.read_csv(StringIO(data), usecols=lambda x: x.upper() in ["A", "C"])
Out[60]: 
   a  c
0  1  3
1  4  6
2  7  9

usecols 參數還可以用於指定最終結果中不使用哪些列

In [61]: pd.read_csv(StringIO(data), usecols=lambda x: x not in ["a", "c"])
Out[61]: 
   b    d
0  2  foo
1  5  bar
2  8  baz

在這個例子中,我們排除了 a 和 c 列

6 注釋和空行6.1 忽略注釋行和空行

如果指定了 comment 參數,則注釋的行將被忽略。默認情況下,空白的行也會被忽略

In [62]: data = "\na,b,c\n  \n# commented line\n1,2,3\n\n4,5,6"

In [63]: print(data)

a,b,c
  
# commented line
1,2,3

4,5,6

In [64]: pd.read_csv(StringIO(data), comment="#")
Out[64]: 
   a  b  c
0  1  2  3
1  4  5  6

如果設置 skip_blank_lines=False,則不會忽略空行和注釋行

In [65]: data = "a,b,c\n\n1,2,3\n\n\n4,5,6"

In [66]: pd.read_csv(StringIO(data), skip_blank_lines=False)
Out[66]: 
     a    b    c
0  NaN  NaN  NaN
1  1.0  2.0  3.0
2  NaN  NaN  NaN
3  NaN  NaN  NaN
4  4.0  5.0  6.0

注意:被忽略的行可能會造成涉及行號的歧義,header 參數使用行號(忽略注釋/空行),而 skiprows 使用行號(包括注釋/空行)

In [67]: data = "#comment\na,b,c\nA,B,C\n1,2,3"

In [68]: pd.read_csv(StringIO(data), comment="#", header=1)
Out[68]: 
   A  B  C
0  1  2  3

In [69]: data = "A,B,C\n#comment\na,b,c\n1,2,3"

In [70]: pd.read_csv(StringIO(data), comment="#", skiprows=2)
Out[70]: 
   a  b  c
0  1  2  3

如果 header 和 skiprows 都指定了,則 header 將相對於 skiprows 的末尾。例如

In [71]: data = (
   ....:     "# empty\n"
   ....:     "# second empty line\n"
   ....:     "# third emptyline\n"
   ....:     "X,Y,Z\n"
   ....:     "1,2,3\n"
   ....:     "A,B,C\n"
   ....:     "1,2.,4.\n"
   ....:     "5.,NaN,10.0\n"
   ....: )
   ....: 

In [72]: print(data)
# empty
# second empty line
# third emptyline
X,Y,Z
1,2,3
A,B,C
1,2.,4.
5.,NaN,10.0


In [73]: pd.read_csv(StringIO(data), comment="#", skiprows=4, header=1)
Out[73]: 
     A    B     C
0  1.0  2.0   4.0
1  5.0  NaN  10.0

6.2 注釋

有時文件中可能包含注釋或元數據:

In [74]: print(open("tmp.csv").read())
ID,level,category
Patient1,123000,x # really unpleasant
Patient2,23000,y # wouldn't take his medicine
Patient3,1234018,z # awesome

默認情況下,解析器在輸出中包括注釋

In [75]: df = pd.read_csv("tmp.csv")

In [76]: df
Out[76]: 
         ID    level                        category
0  Patient1   123000           x # really unpleasant
1  Patient2    23000  y # wouldn't take his medicine
2  Patient3  1234018                     z # awesome

我們可以使用 comment 關鍵字

In [77]: df = pd.read_csv("tmp.csv", comment="#")

In [78]: df
Out[78]: 
         ID    level category
0  Patient1   123000       x 
1  Patient2    23000       y 
2  Patient3  1234018       z 

7 處理 Unicode 數據

encoding 參數應用於編碼 unicode 數據,它將導致字節字符串在結果中需要 unicode 解碼

In [79]: from io import BytesIO

In [80]: data = b"word,length\n" b"Tr\xc3\xa4umen,7\n" b"Gr\xc3\xbc\xc3\x9fe,5"

In [81]: data = data.decode("utf8").encode("latin-1")

In [82]: df = pd.read_csv(BytesIO(data), encoding="latin-1")

In [83]: df
Out[83]: 
      word  length
0  Träumen       7
1    Grüße       5

In [84]: df["word"][1]
Out[84]: 'Grüße'

一些情況下必須指定正確的解碼格式才能正確解析數據

8 索引列和末尾分隔符

如果一個文件的數據列比列名多一列,第一列將被用作 DataFrame 的行名

In [85]: data = "a,b,c\n4,apple,bat,5.7\n8,orange,cow,10"

In [86]: pd.read_csv(StringIO(data))
Out[86]: 
        a    b     c
4   apple  bat   5.7
8  orange  cow  10.0

In [87]: data = "index,a,b,c\n4,apple,bat,5.7\n8,orange,cow,10"

In [88]: pd.read_csv(StringIO(data), index_col=0)
Out[88]: 
            a    b     c
index                   
4       apple  bat   5.7
8      orange  cow  10.0

通常,您可以使用 index_col 參數來實現此行為

當在每個數據行的末尾帶有一個分隔符的文件時,會出現一些異常情況,讓解析器感到頭大。要顯式禁用索引列推斷並放棄最後一列,可以設置 index_col=False

In [89]: data = "a,b,c\n4,apple,bat,\n8,orange,cow,"

In [90]: print(data)
a,b,c
4,apple,bat,
8,orange,cow,

In [91]: pd.read_csv(StringIO(data))
Out[91]: 
        a    b   c
4   apple  bat NaN
8  orange  cow NaN

In [92]: pd.read_csv(StringIO(data), index_col=False)
Out[92]: 
   a       b    c
0  4   apple  bat
1  8  orange  cow

如果使用 usecols 參數提取數據的子集,index_col 的作用將基於該子集,而不是原始數據

In [93]: data = "a,b,c\n4,apple,bat,\n8,orange,cow,"

In [94]: print(data)
a,b,c
4,apple,bat,
8,orange,cow,

In [95]: pd.read_csv(StringIO(data), usecols=["b", "c"])
Out[95]: 
     b   c
4  bat NaN
8  cow NaN

In [96]: pd.read_csv(StringIO(data), usecols=["b", "c"], index_col=0)
Out[96]: 
     b   c
4  bat NaN
8  cow NaN

注意:雖然使用了 usecols 參數,但是由於末尾的分隔符,導致數據的第一列作為索引而無法使數據正確對齊

相關焦點

  • Python 數據處理(十三)—— IO 工具之 CSV
    Python 數據處理(十三)—— IO 工具前言前面我們介紹了 pandas 的基礎語法操作,下面我們開始介紹 pandas 的數據讀寫操作。下面列出了所有的 reader 和 writer 函數注意:後面會用到 StringIO,請確保導入# python3from io import StringIO# python2from StringIO
  • 基於Python實現對各種數據文件的操作
    常見的數據文件類型如下:txtcsvexcel(xls\xlsx)在線網頁數據pdf\word其他數據軟體格式1 txt文件更多參考:https://docs.python.org/3/tutorial/inputoutput.html
  • Python爬蟲 | 0xc - 數據存儲:CSV和Excel
    CSV(Comma-Separated Values,逗號分隔值) 以純文本形式存儲表格數據(數字和文本),記錄間以某種換行符分隔。跟我們上面用-作為分隔符保存數據非常類似,CSV文件除了可以用普通文本編輯工具打開外,還可使用Excel打開。Python中內置一個csv模塊供我們處理CSV文件。
  • python-pandas讀寫csv數據
    https://pandas.pydata.org/pandas-docs/stable/https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html
  • Python對CSV文件的處理
    /usr/bin/env python #-*-coding:utf-8-*-#author:wuyaimport  csvdef readCsv(): with open('csvTest.csv','r') as f: rander=csv.reader(f) #對數據循環獲取
  • Python 簡單操作 CSV
    CSV與Excel區別Python 通過 csv 模塊來實現 CSV 格式文件中數據的讀寫,該模塊提供了兼容 Excel 方式輸出、讀取數據文件的功能,這樣我們無需知道 Excel 所採用 CSV 格式的細節,同樣的它還可以定義其他應用程式可用的或特定需求的 CSV 格式。
  • 大數據下Python的三款大數據分析工具
    導讀:Python在大數據領域中被常用已經不是什麼稀奇事。現在讓我們了解三個Python工具/庫來處理自己的大數據。
  • Python學習第93課-導入csv數據並繪製折線圖
    【每天幾分鐘,從零入門python編程的世界!】之前我們畫各種圖,都是把需要分析的數據,手寫輸入Python的開發工具中去的,這樣做是為了學習和理解Python數據可視化畫圖的原理,但是在實際工作中,我們一定是去處理Python開發工具之外的一些數據,比如Excel表格保存的數據,或者其他格式的文件保存的數據。
  • Python 數據處理(十六)
    Python 數據處理(十六)10 指定浮點數轉換方法可以在 C 引擎解析期間使用 float_precision 參數來指定浮點數轉換器該參數有三個可選的值:round_trip: 保證文件讀寫之後小數點精度不變In [
  • 在Python中導入數據
    在Python中導入數據來源:https://towardsdatascience.com/importing-data-in-python-f6602add57b7作者:Sergi Lehkyi翻譯:老齊閱讀本文需要7分鐘最近,我在DataCamp完成了兩門關於Python數據導入的課程,我對可以用來獲取數據的原始碼數量感到非常驚訝
  • 常用的十大 python 圖像處理工具
    圖片來自 Pexels 的Luriko Yamaguchi今天,在我們的世界裡充滿了數據,圖像成為構成這些數據的重要組成部分。Python成為這種圖像處理任務是一個恰當選擇,這是因為它作為一種科學程式語言正在日益普及,並且在其生態系統中免費提供許多最先進的圖像處理工具供大家使用。讓我們看一下可以用於圖像處理任務中的常用 Python 庫有哪些吧。
  • 如何快速學會Python處理數據?(5000字走心總結)
    所以,要利用工作之餘的時間,把python基礎打紮實。2 Python數據處理示例 2.1  安裝並搭建python環境首先,需要安裝python,我要推薦Anaconda3,從事數據分析的夥伴們,嚴重推薦此軟體!
  • 如何使用PHP處理CSV文件?(代碼示例)
    下面本篇文章就來給大家具體介紹一下使用PHP處理CSV文件的方法,希望對大家有所幫助。什麼是CSV文件?CSV文件基本上只是一個符合特定格式的文本文件,一種用來存儲數據的純文本文件格式,通常用於電子表格或資料庫軟體中。
  • Python3 使用csv模塊處理CSV(逗號分割的值)格式存儲的天氣數據
    模塊處理文件代碼中使用到csv文件, 本文末尾有下載連結分析sitkaweather07-2014.csv文件highs_lows.pyimport csvfrom datetime import datetimefrom matplotlib import pyplot as plt# 從文件中獲取每天的最高溫度
  • python中csv模塊用法(詳細)
    python csv模塊# CSV以純文本存儲數和文本。文件的每一行就代表一條數據,每條記錄包含由逗號分隔一個或多個屬性值。
  • Python數學建模技巧之pandas數據處理
    歷年美賽C題都是關於大數據的題目,再結合近年來大數據處理技術在社會各行各業中應用得越來越普遍,今年的這則通知可能預示著今年C題的數據量會更大。既然提前將數據集公布了出來,準備做C題的隊伍肯定都是會在賽前就將數據集進行一些基本的預處理,包括數據清洗、數據集成、數據轉換、數據規約、數據離散化等操作,甚至在不知道題目的情況下就嘗試著用一些數據挖掘的算法去試圖發現一些數據集中所包含的潛在規律。基本工具Excel肯定沒法去完成這些複雜的數據處理任務,而用matlab去完成這些任務的話,又會極為繁瑣複雜和不方便。
  • Java大數據導出Excel解決方案(POI、JXL、IO流(CSV)對比)
    即數據在兩設備間的傳輸稱為流,流的本質是數據傳輸,根據數據傳輸特性將流抽象為各種類,方便更直觀的進行數據操作,而上面提到的POI和JXL實際都是基於IO流封裝的工具。         該方式採用最原始的形式進行導出工作,選擇合適的流工作效率會非常出色。但是僅支持對文本文件的操作,如:CSV、TXT等,且導出的文件會相對較大。
  • Python數據處理庫pandas入門教程
    在這種情況下,我們可以通過指定分隔符的方式來讀取這個文件,像這樣:實際上,read_csv支持非常多的參數用來調整讀取的參數,如下表所示:詳細的read_csv函數說明請參見這裡:pandas.read_csv處理無效值現實世界並非完美,我們讀取到的數據常常會帶有一些無效值。
  • 教你如何用python輕輕鬆鬆操作Excel、Word、CSV,一文就夠了,趕緊碼住!!!
    Python 操作 Excel常用工具數據處理是 Python 的一大應用場景,而 Excel 又是當前最流行的數據處理軟體。因此用 Python 進行數據處理時,很容易會和 Excel 打起交道。得益於前人的辛勤勞作,Python 處理 Excel 已有很多現成的輪子,比如 xlrd & xlwt & xlutils 、 XlsxWriter 、 OpenPyXL ,而在 Windows 平臺上可以直接調用 Microsoft Excel 的開放接口,這些都是比較常用的工具,還有其他一些優秀的工具這裡就不一一介紹,接下來我們通過一個表格展示各工具之間的特點:類型xlrd
  • Python的可視化工具概述
    >ggplotBokehpygalPlotly在例子用,我將使用pandas操作數據,並啟動其可視化.在大多數情況下使用這些工具不需要pandas,但是我覺得pandas+可視化工具如此普遍,這是最好的起點。