分享

学会文件读取—python(十八)

 生物_医药_科研 2018-12-17

pandas提供了一些用于将表格型数据读取为DataFrame对象的函数。表6-1对它们进行了总结,其中read_csvread_table 可能会是我们今后用得最多的。

首先,我们先看下面一个情况:

import pandas as pd

### 直接读取会报错,这是为什么呢?

df=pd.read_table('G:/python入门/Example.csv',sep=',')

---------------------------------------------------------------------------

OSError                                   Traceback (most recent call last)

input-37-f802989947b5> in <module>()
----> 1 df=pd.read_table('G:/python入门/Example.csv',sep=',')

E:\Anconda\lib\site-packages\pandas\io\parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, escapechar, commentencoding, dialect, tupleize_cols, error_bad_lines, warn_bad_lines, skipfooter, doublequote, delim_whitespace, low_memory, memory_map, float_precision)
    676                     skip_blank_lines=skip_blank_lines)
    677 
--> 678         return _read(filepath_or_buffer, kwds)
    679 
    680     parser_f.__name__ = name

这是因为我们的文件路径里面包含了中文字符,所以会出错,如果我们切换一下路径,变成没有中文的路径,再看一下
df=pd.read_csv('G:Example.csv')

df.head()

```


abcdmessage
01234hello
15678world
29101112foo
这样就不会报错,如果我们就是中文路径,该怎么办呢?我们可以先打开该文件,然后在读进该文件句柄,如下:
f=open('G:python入门/Example.csv')

df=pd.read_csv(f)

df

···


abcdmessage
01234hello
15678world
29101112foo

···

这样就成功读取了
接着我们看到他是默认第一行是作为了Header,如果我们不想把第一行作为header,我们可以设置header=None,这样的话,每列的列头就会用数字填充
df=pd.read_csv('G:Example.csv',header=None)

df

···


01234
0abcdmessage
11234hello
25678world
39101112foo
当然,我们也可以给每一列起一个列名
df=pd.read_csv('G:Example.csv',header=None,names=['A','B','C','D','E'])

df

···


ABCDE
0abcdmessage
11234hello
25678world
39101112foo

···

df.shape

(45)

str(df)

'   A   B   C   D        E\n0  a   b   c   d  message\n1  1   2   3   4    hello\n2  5   6   7   8    world\n3  9  10  11  12      foo'
假如我们想给df的索引重新命名,就是把最后一列当成索引名,可以通过index_col 参数指定
df=pd.read_csv('G:Example.csv',header=None,names=['A','B','C','D','E'],index_col='E')

df

···


ABCD
E



messageabcd
hello1234
world5678
foo9101112
如果希望将多个列做成一个层次化索引,只需传入由列编号或列名组成的列表即可:
df2=pd.read_csv('G:test.csv',index_col=['key1','key2'])

df2

···



value1value2
key1key2

onea12
b34
c56
d78
twoa910
b1112
c1314
d1516

···

df2=pd.read_csv('G:test.csv',index_col=['key2','key1'])

df2

···



value1value2
key2key1

aone12
bone34
cone56
done78
atwo910
btwo1112
ctwo1314
dtwo1516
pd.read_table()函数
有的时候我们读取的文件是以空格间隔的,这种情况下,你可以传递一个正则表达式作为read_table 的分隔符。可
以用正则表达式表达为\s+ ,于是有:

···

rf=pd.read_table('G:/test1.txt',sep='\s+')

rf

···


ABC
aaa-0.264438-1.026059-0.619500
bbb0.9272720.302904-0.032399
ccc-0.264273-0.386314-0.217601
ddd-0.871858-0.3483821.100491
这里,由于列名比数据行的数量少,所以read_table 推断第一列应该是DataFrame的索引。
这些解析器函数还有许多参数可以帮助你处理各种各样的异形文件格式。比如说,你可以用skiprows 跳过文件的第一行、第三行和第四行:
df=pd.read_table('G:/test1.txt',sep='\s+')

df['A']

aaa   -0.264438
bbb    0.927272
ccc   -0.264273
ddd   -0.871858
Name: A, dtype: float64

df=pd.read_table('G:/test1.txt',sep='\s+',skiprows=[1])

df

···


ABC
bbb0.9272720.302904-0.032399
ccc-0.264273-0.386314-0.217601
ddd-0.871858-0.3483821.100491
缺失值处理是文件解析任务中的一个重要组成部分。缺失数据经常是要么没有(空字符串),要么用某个标记值表示。默认情况下,pandas会用一组
经常出现的标记值进行识别,比如NA及NULL:
kk1=pd.read_table('G:/test2.txt',sep=',')

pd.isnull(kk1)

somethingabcdmessage
0FalseFalseFalseFalseFalseTrue
1FalseFalseFalseTrueFalseFalse
2FalseFalseFalseFalseFalseFalse
na_values 可以用一个列表或集合的字符串表示缺失值:
kk=pd.read_table('G:/test2.txt',sep=',', na_values=['NULL'])

pd.isnull(kk)

somethingabcdmessage
0FalseFalseFalseFalseFalseTrue
1FalseFalseFalseTrueFalseFalse
2FalseFalseFalseFalseFalseFalse

逐块读取文本文件

在处理很大的文件时,或找出大文件中的参数集以便于后续处理时,你可能只想读取文件的一小部分或逐块对文件进行迭代。在看大文件之前,我们先设置pandas显示地更紧些:
pd.options.display.max_rows = 10  #显示最多展示10行
如果只想读取几行(避免读取整个文件),通过nrows 进行指定即可pd.read_csv('examples/ex6.csv', nrows=5)要逐块读取文件,可以指定chunksize(行数):chunker = pd.read_csv('ch06/ex6.csv', chunksize=1000)
将数据写出到文本格式
利用DataFrame的to_csv 方法,我们可以将数据写到一个以逗号分隔的文件中:
kk1.to_csv('G:/kk.csv')
当然,还可以使用其他分隔符
kk1.to_csv('G:/kk2.txt',sep='|')
这里我们可以直接写出到sys.stdout ,他仅仅是打印出文本结果而已
import sys

kk1.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

kk1.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

kk1.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

缺失值在输出结果中会被表示为空字符串。你可能希望将其表示为别的标记值:

kk.to_csv(sys.stdout,na_rep='NULL')

,something,a,b,c,d,message
0,one,1,2,3.0,4,NULL
1,two,5,6,NULL,8,world
2,three,9,10,11.0,12,foo

如果没有设置其他选项,则会写出行和列的标签。当然,它们也都可以被禁用:

kk.to_csv(sys.stdout,na_rep='NULL',index=False,header=False)

one,1,2,3.0,4,NULL
two,5,6,NULL,8,world
three,9,10,11.0,12,foo

此外,你还可以只写出一部分的列,并以你指定的顺序排列:

kk.to_csv(sys.stdout,index=False,columns=['a','c'])

a,c
1,3.0
5,
9,11.0
处理分隔符格式

大部分存储在磁盘上的表格型数据都能用pandas.read_table进行加载。然而,有时还是需要做一些手工处理。

由于接收到含有畸形行的文件而使read_table 出毛病的情况并不少见。为了说明这些基本工具,看看下面这个简单的CSV文件:

pd.read_table('G:/kk3.txt',sep=',')

···


abc
0123
1123

···

import csv

f = open('G:/kk3.txt')

reader = csv.reader(f)
对这个reader 进行迭代将会为每行产生一个元组(并移除了所有的引号):
for line in reader:
    print(line)
['a''b''c']
['1''2''3']
['1''2''3']

lines = list(reader)

lines

[['a''b''c'], ['1''2''3'], ['1''2''3']]

with open('G:/kk3.txt'as f:
     lines = list(csv.reader(f))

lines

[['a''b''c'], ['1''2''3'], ['1''2''3']]
然后,我们将这些行分为标题行和数据行:
header, values = lines[0], lines[1:]

header

['a''b''c']

values

[['1''2''3'], ['1''2''3']]
然后,我们可以用字典构造式和zip(*values),后者将行转置为列,创建数据列的字典:
data_dict = {h: v for h, in zip(header, zip(*values))}

data_dict

{'a': ('1''1'), 'b': ('2''2'), 'c': ('3''3')}
要手工输出分隔符文件,你可以使用csv.writer。它接受一个已打开且可写的文件对象以及跟csv.reader 相同的那些语支和格式化选项:
with open('G:/mydata.csv''w'as f:
    writer 
= csv.writer(f)
    writer.writerow(('one''two''three'))
    writer.writerow(('1''2''3'))
    writer.writerow(('4''5''6'))
    writer.writerow(('7''8',  '9'))


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多