# -*- coding: utf-8 -*-
"""
Created on Tue Aug 28 22:19:26 2018
 
@author: Dev
"""
import numpy as np
import pandas as pd
import sys
import csv
import xlrd, xlwt
import json
 
读取csv格式文件
ex1.csv的文件内容:
 
 
path = 'D:\Learning\Program\Python Data Analyze'    # 设置文件路径
df = pd.read_csv(path + '\\data\\ex1.csv') # 自动识别csv文件的分隔符
df1 = pd.read_table(path + '\\data\\ex1.csv', sep=',') # 需手动指定分隔符 #执行结果(df和df1相同):
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo

ex2.csv内容:

df2 = pd.read_csv(path + '\\data\\ex2.csv', header=None)    # 指定文件中没有column,会自动根据列的数量指定

#执行结果:
0 1 2 3 4
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
# 设置列名,并将message列设置为索引列
names = ['a', 'b', 'c', 'd', 'message']
df3 = pd.read_csv(path + '\\data\\ex2.csv', names=names, index_col='message')
print(df3.index)
print(df3) #执行结果:
Index(['hello', 'world', 'foo'], dtype='object', name='message') a b c d
message
hello 1 2 3 4
world 5 6 7 8
foo 9 10 11 12
csv_mindex.csv内容:
 
# 将两列设置为索引
parsed = pd.read_csv(path + '\\data\\csv_mindex.csv', index_col=['key1', 'key2'])
print(parsed) #执行结果:
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
# ex3.txt中有多种空格类型(空格 TAB等)

# 将txt文件转为列表格式(转换后格式较乱,不易使用)
list_a = list(open(path + '\\data\\ex3.txt'))
print(list_a) --执行结果:
[' A B C\n',
'aaa -0.264438 -1.026059 -0.619500\n',
'bbb 0.927272 0.302904 -0.032399\n',
'ccc -0.264273 -0.386314 -0.217601\n',
'ddd -0.871858 -0.348382 1.100491\n'] # 在分隔符中使用正则表达式对数据进行分割(\s 表示多种不可见字符, +表示存在多个)
result = pd.read_table(path + '\\data\\ex3.txt', sep='\s+')
print(result) # 执行结果:
A B C
aaa -0.264438 -1.026059 -0.619500
bbb 0.927272 0.302904 -0.032399
ccc -0.264273 -0.386314 -0.217601
ddd -0.871858 -0.348382 1.100491

ex4.csv内容:

# 跳过指定行
df4 = pd.read_csv(path + '\\data\\ex4.csv', skiprows=[0, 2, 3])
print(df4) #执行结果:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
 ex5.csv内容:
 
df5 = pd.read_csv(path + '\\data\\ex5.csv')
print(df5)
print(pd.isnull(df5)) # 判断是否有为空的值 #执行结果:
something a b c d message
0 one 1 2 3.0 4 NaN
1 two 5 6 NaN 8 world
2 three 9 10 11.0 12 foo something a b c d message
0 False False False False False True
1 False False False True False False
2 False False False False False False # 将指定的值设置为空值
df5 = pd.read_csv(path + '\\data\\ex5.csv', na_values=['NULL'])
print(df5) #执行结果:
something a b c d message
0 one 1 2 3.0 4 NaN
1 two 5 6 NaN 8 world
2 three 9 10 11.0 12 foo # 设置多个na_values值
sentinels = {'message': ['foo', 'NA'], 'something': ['two']}
df5 = pd.read_csv(path + '\\data\\ex5.csv', na_values=sentinels)
print(df5) #执行结果:
something a b c d message
0 one 1 2 3.0 4 NaN
1 NaN 5 6 NaN 8 world
2 three 9 10 11.0 12 NaN

ex6.csv内容:

一共9999行数据,后面省略。。。

# 逐行读取
result = pd.read_csv(path + '\\data\\ex6.csv')
print(result) # 行数过多时,一次读取所有行会显得多余 # 执行结果:
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
5 1.817480 0.742273 0.419395 -2.251035 Q
6 -0.776764 0.935518 -0.332872 -1.875641 U
... ... ... ... ..
9995 2.311896 -0.417070 -1.409599 -0.515821 L
9996 -0.479893 -0.650419 0.745152 -0.646038 E
9997 0.523331 0.787112 0.486066 1.093156 K
9998 -0.362559 0.598894 -1.843201 0.887292 G
9999 -0.096376 -1.012999 -0.657431 -0.573315 0 df = pd.read_csv(path + '\\data\\ex6.csv', nrows=5) # 只读取前5行 # 执行结果:
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 # 将1000行数据存储到chunker中
chunker = pd.read_csv(path + '\\data\\ex6.csv', chunksize=1000)
print(chunker) # 执行结果:
<pandas.io.parsers.TextFileReader object at 0x000000000BCC4F98> # 再统计key值的取值次数
total = pd.Series([])
for piece in chunker:
total = total.add(piece['key'].value_counts(), fill_value=0) # fill_value 使用0填充空值
print(total[:10]) # 执行结果:
0 151.0
1 146.0
2 152.0
3 162.0
4 171.0
5 157.0
6 166.0
7 164.0
8 162.0
9 150.0
dtype: float64
注:df.column.values 和 df.column.value_counts()的区别:
values以列表形式返回指定column的所有取值
value_counts()返回指定column的不同取值次数
value_counts(1)返回指定column的不同取值频率
 
 
文件写出
data = pd.read_csv(path + '\\data\\ex5.csv')
print(data) # 执行结果
something a b c d message
0 one 1 2 3.0 4 NaN
1 two 5 6 NaN 8 world
2 three 9 10 11.0 12 foo
data.to_csv(path + '\\data\\ex5_2.csv') # 写出文件到指定目录(windows下,后面要输出的文件名开头必须有个表示路径的'\\',不然不会生成文件,也不报错,很诡异。。。)

输出的ex5_2.csv的内容:

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
data.to_csv(sys.stdout, na_rep='NULL')  # 以NULL填充na值

# 执行结果
,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
data.to_csv(sys.stdout, index=False, header=False)  #   不选取索引名和列名

# 执行结果:
one,1,2,3.0,4,
two,5,6,,8,world
three,9,10,11.0,12,foo
data.to_csv(sys.stdout, index=False, columns=['a', 'b', 'c'])   # 重新设置列名

# 执行结果:
a,b,c
1,2,3.0
5,6,
9,10,11.0

# 将Series写入csv文件:

# pd.date_range() 用于生成一个固定频率的时间索引
dates = pd.date_range('1/1/2000', periods=7, freq='H') # start 起始值, end 结束值, freq频率, periods周期
ts = pd.Series(np.arange(7), index=dates) # 使用生成的时间索引指定
ts.to_csv(path + '\\data\\tseries.csv')
print(ts.index) # 执行结果:
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 01:00:00',
'2000-01-01 02:00:00', '2000-01-01 03:00:00',
'2000-01-01 04:00:00', '2000-01-01 05:00:00',
'2000-01-01 06:00:00'],
dtype='datetime64[ns]', freq='H')

生成的tseries.csv的内容:

# parse_dates 指定某些列是否被解析为日期,布尔值或列表
data2 = pd.read_csv(path + '\\data\\tseries.csv', header=None, parse_dates=True)
print(data2) # 执行结果:
0 1
0 2000-01-01 00:00:00 0
1 2000-01-01 01:00:00 1
2 2000-01-01 02:00:00 2
3 2000-01-01 03:00:00 3
4 2000-01-01 04:00:00 4
5 2000-01-01 05:00:00 5
6 2000-01-01 06:00:00 6
Tips: 如果IDE包含IPython(我用的是Spyder),在IPython界面输入  cd $path命令即可进入path变量所指定的目录下,就不用每次读取和写出时都带path了。

ex7.csv内容:

f = open('ex7.csv')    # 打开csv文件
reader = csv.reader(f) # 使用csv.reader()读取
for line in reader: # 逐行打印
print(line) # 执行结果:
['a', 'b', 'c']
['', '', '']
['', '', '', ''] # 转换成列表
lines = list(csv.reader(open('ex7.csv')))
header, values = lines[0], lines[1:] # 取第一行作为header,其余行作为values
# 先将values解压为元组,再与header合并,组成字典
data_dict = {h: v for h,v in zip(header, zip(*values))}
print(data_dict) # 执行结果:
{'a': ('', ''), 'b': ('', ''), 'c': ('', '')}

使用csv.Dialect自定义文件格式

# 通常用于数据中包含特殊字符的情况
 
class my_dialect(csv.Dialect):
  # 自定义一个继承csv.Dialect的类
lineterminator = '\n' # 每行结束符
delimiter = ';' # 定义分隔符
quotechar = '"' # 定义给包含特殊字符的数据所添加的符号
quoting = csv.QUOTE_MINIMAL # 仅对包含特殊字符的数据加quotechar中定义的符号 csv.register_dialect('mycsv', my_dialect) # 使用自定义名称mycsv 注册上面的类
with open('mydata.csv', 'w') as file_obj:  # 使用自定义文件格式写入数据
writer = csv.writer(file_obj, 'mycsv')
writer.writerow(('one', 'two', 'three'))
writer.writerow(('', '', ''))
writer.writerow(('', '', ''))
writer.writerow(('', '', ''))
生成的mydata.csv内容:

在mydata.csv文件中加入特殊符号(5前面加了单引号):

# 不带dialect的读取:
with open('mydata.csv', 'r') as file_obj:
reader = csv.reader(file_obj)
for row in reader:
print(row) # 执行结果:
['one;two;three']
['1;2;3']
["4;'5;6"]
['7;8;9']
# 带dialect的读取:
with open('mydata.csv', 'r') as file_obj:
reader = csv.reader(file_obj, dialect='mycsv')
for row in reader:
print(row) # 执行结果:
['one', 'two', 'three']
['', '', '']
['', "'5", '']
['', '', '']

发现在使用了自定义的dialect后,只有带特殊符号的数据被加了双引号("'5")

 
 
将数据转储为Excel的xls工作薄(xlwt)
wb = xlwt.Workbook()
print(wb) # Workbook类型的对象 # 执行结果:
<xlwt.Workbook.Workbook object at 0x000000000BD1DC88>
wb.add_sheet('first_sheet', cell_overwrite_ok=True) # 新增名为first_sheet的sheet页,并且可覆盖写入
wb.get_active_sheet()   # 获取当前sheet页序号
ws_1 = wb.get_sheet(0)  # 根据获取的序号激活该sheet页
print(ws_1)

wb.add_sheet('first_sheet', cell_overwrite_ok=True) # 新增名为first_sheet的sheet页,并且可覆盖写入
wb.get_active_sheet() # 获取当前sheet页序号
ws_1 = wb.get_sheet(0) # 根据获取的序号激活该sheet页
print(ws_1) # 执行结果:
<xlwt.Worksheet.Worksheet object at 0x000000000BD1D748>
ws_2 = wb.add_sheet('second_sheet') # 在wb中再增加一张sheet页ws_2
data = np.arange(1, 65).reshape(8, 8)
ws_1.write(0, 0, 100) # 在0行0列的位置写入100 # 将生成的data分别写入wb的两个sheet页中
for row in range(data.shape[0]):
for col in range(data.shape[1]):
# 需要将数据类型为numpy.int32的数组元素转换为int类型
ws_1.write(row, col, int(data[row, col])) # 先写行,后写列
ws_2.write(row, col, int(data[col, row])) # 先写列, 后写行 wb.save('workbook.xls') # 保存结果到xls文件中

first_sheet:

second_sheet:

生成xlsx工作簿(xlrd)
book = xlrd.open_workbook('workbook.xls')   # 读取刚才生成的工作簿文件
print(book) # Book对象 # 执行结果:
<xlrd.book.Book object at 0x000000000BC5B9E8>
常用方法:
print(book.nsheets)    # 查看sheet总页数
print(book.sheet_names()) # 查看所有的sheet页名 # 执行结果:
2
['first_sheet', 'second_sheet']
sheet_1 = book.sheet_by_name('first_sheet')  # 通过页名获取sheet页
sheet_2 = book.sheet_by_index(1) # 通过索引获取sheet页
print(sheet_1.name) # sheet页名称
print(sheet_1.nrows) # 总行数
print(sheet_1.ncols) # 总行数 # 执行结果:
first_sheet
8
8
c1 = sheet_1.cell(0, 0)   # 返回(0, 0)(返回类型为xlrd.sheet.Cell)
print(c1)
print(c1.value) # 只返回实际值
print(c1.ctype) # 返回c1对应的数据类型(0: None, 1: string, 2: number, 3: date, 4: bool, 5: error) # 执行结果:
number:1.0
1.0
2
print(sheet_2.row(1))   # 获取第1行的数据
result = [number.value for number in sheet_2.row(1)]# 通过.value获取实际值
print(result) # 执行结果:
[number:2.0, number:10.0, number:18.0, number:26.0, number:34.0, number:42.0, number:50.0, number:58.0]
[2.0, 10.0, 18.0, 26.0, 34.0, 42.0, 50.0, 58.0]
print(sheet_2.row_values(1))    # 直接返回包含实际值的列表,省去了上面的转换过程
print(sheet_2.row_types(0)) # 返回第0行的数据类型列表(对应关系同ctype) # 执行结果:
[2.0, 10.0, 18.0, 26.0, 34.0, 42.0, 50.0, 58.0]
array('B', [2, 2, 2, 2, 2, 2, 2, 2])
print(sheet_2.col(3))   # 获取第4列的数据
print(sheet_2.col_values(3, start_rowx=3, end_rowx=7)) # 获取第四列中第4行到第7行的数据
print(sheet_2.row_values(3, start_colx=3, end_colx=7)) # 获取第四行中第4列到第7列的数据 # 执行结果:
[number:25.0, number:26.0, number:27.0, number:28.0, number:29.0, number:30.0, number:31.0, number:32.0]
[28.0, 29.0, 30.0, 31.0]
[28.0, 36.0, 44.0, 52.0]
# 逐行打印
for row in range(sheet_1.ncols):
for col in range(sheet_1.nrows):
print(sheet_1.cell(row, col).value) # 执行结果:
1.0
2.0
3.0
4.0
5.0
... ...
60.0
61.0
62.0
63.0
64.0

其他常用的数据格式

JSON格式
# 定义一个字符串类型的变量
obj = """
{"name": "Wes",
"places_lived": ["United States", "Spain", "Germany"],
"pet": null,
"siblings": [{"name": "Scott", "age": 25, "pet": "Zuko"},
{"name": "Katie", "age": 33, "pet": "Cisco"}]
}
"""
result = json.loads(obj) # 字符串 -> 字典
print(result) asjson = json.dumps(result) # 字典 -> 字符串
print(asjson) siblings = pd.DataFrame(result['siblings'], columns=['name', 'age', 'pet']) # 字典 -> DataFrame
print(siblings) # 执行结果:
{'name': 'Wes', 'places_lived': ['United States', 'Spain', 'Germany'], 'pet': None, 'siblings': [{'name': 'Scott', 'age': 25, 'pet': 'Zuko'}, {'name': 'Katie', 'age': 33, 'pet': 'Cisco'}]} {"name": "Wes", "places_lived": ["United States", "Spain", "Germany"], "pet": null, "siblings": [{"name": "Scott", "age": 25, "pet": "Zuko"}, {"name": "Katie", "age": 33, "pet": "Cisco"}]} name age pet
0 Scott 25 Zuko
1 Katie 33 Cisco
二进制数据格式
df = pd.read_csv('ex1.csv')
df.to_pickle('frame_pickle.bin') # DataFrame -> 二进制格式
pickle = pd.read_pickle('frame_pickle.bin') # 二进制 -> DataFrame
print(pickle) # 执行结果:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo

查看转换的frame_pickle.bin二进制文件内容:

HDF5格式(可压缩格式)
使用高性能HD5格式进行数据存储和访问,格式类似字典,适合存储格式统一的分层(hierarchical)数据
相关链接:
store = pd.HDFStore('mydata.h5')    # 生成存储文件
store['obj1'] = df # 将数据保存在指定data_column下
store['obj1_col'] = df['a']
print(store)
print(store['obj1']) # 使用data_column访问数据
store.close() # 关闭文件,然后会将store中的数据实际写入本地文件 # 执行结果:
<class 'pandas.io.pytables.HDFStore'>
File path: mydata.h5
/obj1 frame (shape->[3,5])
/obj1_col series (shape->[3]) a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo

关闭后在本地查看mydata.h5文件:

HDF5的压缩模式
data = pd.DataFrame(np.random.standard_normal((10000000, 10)))    # 使用标准正态分布生成一个较大数据量的DF进行对比
normal_store = pd.HDFStore('normal_store.h5') # 普通方式
normal_store['data'] = data
normal_store.close()
# complevel指定压缩强度(0->9 数值越大,强度越高,0是不压缩)
# complib指定要使用的压缩库。可用的lib:
# zlib: 默认lib
# lzo: 压缩和解压都快
# bzip2: 压缩率高
# blosc: 压缩和解压都快
# pandas 0.20.2中又细分除了几种压缩lib,这里就不做详细介绍了
compress_store = pd.HDFStore('compress_store.h5', complevel=9, complib='bzip2') # 这里选择压缩率和强度较高的方式进行压缩
compress_store['data'] = data
compress_store.close()

对比文件大小:

压缩了约144MB, 好像也不是特别明显,是不是数据量还不够大。。。 ):

 

pandas学习笔记 - 文件的写入和输出的更多相关文章

  1. python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码

    python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...

  2. 《python基础教程(第二版)》学习笔记 文件和素材(第11章)

    <python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...

  3. 【转】Pandas学习笔记(一)基本介绍

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  4. Java学习-022-Properties 文件数据写入

    Properties 配置文件写入主要通过 Properties.setProperty 和 Properties.store 两个方法,此文以一个简单的 properties 文件写入源码做示例. ...

  5. Pandas 学习笔记

    Pandas 学习笔记 pandas 由两部份组成,分别是 Series 和 DataFrame. Series 可以理解为"一维数组.列表.字典" DataFrame 可以理解为 ...

  6. 【转】Pandas学习笔记(七)plot画图

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  7. 【转】Pandas学习笔记(六)合并 merge

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  8. 【转】Pandas学习笔记(五)合并 concat

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  9. 【转】Pandas学习笔记(四)处理丢失值

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

随机推荐

  1. js(Mandango:壮汉专用,电影院划位工具)

    Mandango:壮汉专用,电影院划位工具 <body onload="initSeats();"> <div style="margin-top:75 ...

  2. [luogu2513 HAOI2009] 逆序对数列 (计数dp)

    题目描述 对于一个数列{ai},如果有iaj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那么逆序对数为k的这样自然数数列到底有多少个? ...

  3. 洛谷 P1582 倒水 (二进制)

    这道题实际上是考二进制 很容易看出杯子水量一定是2的i次方 所以n杯水最后剩下的水一定是n用二进制表示中1的个数 所以就枚举n来求什么时候1的个数小于k 那么这里有个优化,不然会超时 因为每次加的目的 ...

  4. 浅谈密码加SALT原理

    我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码.  加Salt可以一定程度上解决这一问题.所谓加Salt方法, ...

  5. fensorflow 安装报错 DEPENDENCY ERROR

    1.错误信息 DEPENDENCY ERROR The target you are trying to run requires an OpenSSL implementation. Your sy ...

  6. spring boot学习(转)

    玩转Spring Boot 前言         首先在这里对Spring Boot做个简单的介绍,对Spring Boot也关注了挺久了,Spring Boot是由Pivotal团队提供的全新框架, ...

  7. ASP.NET-AJAX.FORM提交附件失败

    尝试了不少时间在AJAX.FORM提交附件,发现完全不行,经过下面的这个博客的介绍,使用ajax.form.js插件提交成功,记录一下该博文网址和结论: 相关网址:http://www.cnblogs ...

  8. Revit二次开发实现BIM盈利(以橄榄山快模为例解说) 视频讲座下载

    应笔墨闲谈群的邀请, 在10月11号晚8:30分在其群做了一次关于BIM二次开发的讲座. 因为參与者基本上都是从设计院和施工单位来的,所以对Revit二次开发做了纵览性的解说, 以非程序猿能听懂的方式 ...

  9. 【Java】【Flume】Flume-NG启动过程源代码分析(一)

    从bin/flume 这个shell脚本能够看到Flume的起始于org.apache.flume.node.Application类,这是flume的main函数所在. main方法首先会先解析sh ...

  10. the process android.process.acore has stopped或the process com.phone。。。。

    模拟器一启动 The process android.process.acore has stopped unexpectedly 今天不知道怎么回事,模拟器一启动就狂报错, 模拟器已经重新安装过了, ...