python文件处理

1 从txt文本文件中读取数据

   有下列常见方法

           read_csv        从文件、URL、类似文件的对象中读取数据,默认使用逗号为分隔符号

           read_table      从文件、URL、类似文件的对象中读取数据,默认使用tab ('\t')为分隔符号

           read_fwf         从固定宽度的列格式文件读取数据

 

其中read_csv方法相关参数及说明

Argument                  Description                                                                                   

path                          文件路径,URL

sep or delimiter        用来分割行的的字符序列或者表达式

header                      作为列名称的行号,默认为0(第一行),如果没有列名,需要指明header=None

index_col                  作为结果中的行索引的列名称或列序号

skiprows                   从文件开始读取时跳过的行序号

na_values                 用NA值替换的值

parse_dates             将date数据解析成datetime,默认是False,为True时将解析所有列

keep_date_col          如果将指定列进行日期解析(parse date)删除指定列,默认为True

.................

 

(1)正常读取

 假若有 如下csv文件(ex1.csv)

         a,b,c,d,message

        1,2,3,4,hello

        5,6,7,8,world

        9,10,11,12,foo

  使用read_csv方法,由于默认是以逗号为分割符号,所以直接使用。(

  注:下列方法等同于:pd.read_table('ch06/ex1.csv', sep=','),假若有多个空格作为分割符号,read_table中的sep='\s+'

In [847]: df = pd.read_csv('ch06/ex1.csv') 

In [848]: df 

Out[848]: a b c d message 

        0 1 2 3 4 hello 

        1 5 6 7 8 world 

        2 9 10 11 12 foo 

(2)文件中没有指定列名。

 如下csv文件(ex2.csv)

        1,2,3,4,hello

        5,6,7,8,world

        9,10,11,12,foo

声明header为空

In [851]: pd.read_csv('ch06/ex2.csv', header=None) 

Out[851]:    X.1  X.2  X.3  X.4    X.5 

         0  1    2    3    4  hello 

         1  5    6    7    8  world 

         2  9   10   11   12    foo

或者指定列名

In [852]: pd.read_csv('ch06/ex2.csv', names=['a', 'b', 'c', 'd', 'message']) 

Out[852]:    a   b   c   d message 

          0  1   2   3   4   hello 

          1  5   6   7   8   world 

          2  9  10  11  12     foo

(3)使用index_col参数

       指定 索引列的列名称

In [853]: names = ['a', 'b', 'c', 'd', 'message']
In [854]: pd.read_csv('ch06/ex2.csv', names=names, index_col='message') 

Out[854]:          a   b   c   d 

            message               

            hello 1   2   3   4 

            world 5   6   7   8 

            foo   9  10  11  12

   还可以通过传给多列指定相同前缀,来构造层次索引,只需要传入 列编号或列名称即可

In [855]: !cat ch06/csv_mindex.csv 

key1,key2,value1,value2 

one,a,1,2 

one,b,3,4 

one,c,5,6 

one,d,7,8 

two,a,9,10 

two,b,11,12 

two,c,13,14

two,d,15,16

In [856]: parsed = pd.read_csv('ch06/csv_mindex.csv', index_col=['key1', 'key2'])
In [857]: parsed Out[857]: 

        value1  value2 

key1 key2                

one  a          1       2     

     b          3       4     

     c          5       6     

     d          7       8 

two  a          9      10     

     b         11      12     

     c         13      14     

     d         15      16

(4)有选择的读取和 有选择的使用空值替换

   假若我们有如下数据:

In [861]: !cat ch06/ex4.csv 

# hey! a,b,c,d,message

 # just wanted to make things more difficult for you 

# who reads CSV files with computers, anyway? 

1,2,3,4,hello 

5,6,7,8,world 

9,10,11,12,foo 

跳过其中的指定行,使用参数skiprows

In [862]: pd.read_csv('ch06/ex4.csv', skiprows=[0, 2, 3]) 

Out[862]:    a   b   c   d message

         0  1   2   3   4   hello 
  
         1  5   6   7   8   world 
         2  9  10  11  12     foo

假若有数据如下(第3行5列缺失,2行5列为NaN):

In [863]: !cat ch06/ex5.csv 

something,a,b,c,d,message o

ne,1,2,3,4,NA 

two,5,6,,8,world 

three,9,10,11,12,foo

使用dict类型数据中行列信息指定用空值替换某些记录,使用参数na_values 

In [869]: sentinels = {'message': ['foo', 'NA'], 'something': ['two']}
In [870]: pd.read_csv('ch06/ex5.csv', na_values=sentinels) 

Out[870]:   something  a   b   c   d message 

            0       one  1   2   3   4     NaN 

            1       NaN  5   6 NaN   8   world 

            2     three  9  10  11  12    NaN

 

(5)分片段读取文本

      只读取前几行,使用参数nrow

    
In [873]: pd.read_csv('ch06/ex6.csv', nrows=5) 

Out[873]:         one       two     three      four key 

                 0  0.467976 -0.038649 -0.295344 -1.824726   L 

                 1 -0.358893  1.404453  0.704965 -0.200638   B 

                 2 -0.501840  0.659254 -0.421691 -0.057688   G 

                 3  0.204886  1.074134  1.388361 -0.982404   R 

                 4  0.354628 -0.133116  0.283763 -0.837063   Q

    使用chunksize来指定读取的行数,注意一个chunksize,返回的是可以迭代的数据对象

chunker = pd.read_csv('ch06/ex6.csv', chunksize=1000)
tot = Series([]) 

迭代读取根据属性chunksize指定的文件片段。下列代码是统计文件 ex6.csv前1000行中,”key“列不同值的数量

for piece in chunker:   

           tot = tot.add(piece['key'].value_counts(), fill_value=0)
tot = tot.order(ascending=False) 

In [877]: tot[:10] 

Out[877]:      E    368 

               X    364

               L    346 

               O    343 

               Q    340 

               M    338 

               J    337 

               F    335 

               K    334 

               H    330

 

2  写出文件

    写出文件使用的是 to_csv方法,方法默认使用逗号作为分隔符,可以通过参数 sep修改。默认第一行作为列名,第一列作为行名,可以分别通过参数index=False,header=False修改。
  有如下文件:

In [878]: data = pd.read_csv('ch06/ex5.csv')
In [879]: data Out[879]:   something  a   b   c   d message 

                      0     one  1   2   3   4     NaN 

                      1     two  5   6 NaN   8   world 

                      2     three  9  10  11  12     foo

如果使用参数sys.stdout,代表直接打印

In [882]: data.to_csv(sys.stdout, sep='|') 

|something|a|b|c|d|message

0|one|1|2|3.0|4| 

1|two|5|6||8|world 

2|three|9|10|11.0|12|foo


3 处理XML、HTML文件

   python有多个包可以用来处理XML和HTML文件,其中 lxml 包最为强大。先使用lxml.html来接受HTML文件再使用lxml.objectify来解析。

下述代码获取的是雅虎金融股票数据:

from lxml.html import parse

from urllib2 import urlopen
parsed = parse(urlopen('http://finance.yahoo.com/q/op?s=AAPL+Options'))
doc = parsed.getroot()


通过以上 doc对象,我们可以抽取任何HTML文件标签内容,使用findall方法。下面的代码用来获取标签<a>(即超链接)的位置

In [906]: links = doc.findall('.//a')
In [907]: links[15:20] 

Out[907]: [<Element a at 0x6c488f0>,

           <Element a at 0x6c48950>, 

           <Element a at 0x6c489b0>, 

           <Element a at 0x6c48a10>, 

           <Element a at 0x6c48a70>]

以上对象只是HTML元素,想进一步获得URL和链接文本,需要使用get方法,如果想获得URL中呈现文本,需要使用text_content方法

In [908]: lnk = links[28]
In [909]: lnk 

Out[909]: <Element a at 0x6c48dd0>
In [910]: lnk.get('href') 

Out[910]: 'http://biz.yahoo.com/special.html'
In [911]: lnk.text_content() 

Out[911]: 'Special Editions' 

使用 lxml.objectify来解析XML文件。
  一下文件是 纽约地铁交通运输署的一份关于地铁和公交运输服务的说明书。一下是部分数据示例:

<INDICATOR>  

<INDICATOR_SEQ>373889</INDICATOR_SEQ>  

<PARENT_SEQ></PARENT_SEQ> 

     <AGENCY_NAME>Metro-North Railroad</AGENCY_NAME>  

    <INDICATOR_NAME>Escalator Availability</INDICATOR_NAME>  

    <DESCRIPTION>Percent of the time that escalators are operational  systemwide. The availability rate is based on physical observations performed  the morning of regular business days only. This is a new indicator the agency  began reporting in 2009.

   </DESCRIPTION>  

  <PERIOD_YEAR>2011</PERIOD_YEAR>  

  <PERIOD_MONTH>12</PERIOD_MONTH>  

   <CATEGORY>Service Indicators</CATEGORY>  

  <FREQUENCY>M</FREQUENCY>  

   <DESIRED_CHANGE>U</DESIRED_CHANGE>  

  <INDICATOR_UNIT>%</INDICATOR_UNIT>  

   <DECIMAL_PLACES>1</DECIMAL_PLACES> 

   <YTD_TARGET>97.00</YTD_TARGET>  

   <YTD_ACTUAL></YTD_ACTUAL>  

   <MONTHLY_TARGET>97.00</MONTHLY_TARGET>  

    <MONTHLY_ACTUAL></MONTHLY_ACTUAL> 

</INDICATOR>

使用 lxml.objectify的getroot方法将得到XML文件的根节点

from lxml import objectify
path = 'Performance_MNR.xml' 

parsed = objectify.parse(open(path)) 

root = parsed.getroot()

     使用root.INDICATOR可以获得相应XML元素每个INDICATOR记录的迭代器,对每条记录,可以通过字典数据类型来选择性排除部分不需要的标签。

data = []
skip_fields = ['PARENT_SEQ', 'INDICATOR_SEQ', 'DESIRED_CHANGE', 'DECIMAL_PLACES']  #排除的元素标签
for elt in root.INDICATOR:    

      el_data = {}    

      for child in elt.getchildren():        

               if child.tag in skip_fields:            

                        continue        

              el_data[child.tag] = child.pyval    

                       data.append(el_data)


4 读取Excel文件

xls_file = pd.ExcelFile('data.xls') 

table = xls_file.parse('Sheet1')





 





 




 


 

 

你可能感兴趣的:(python,文件)