# -*- 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内容:
一共10000行,后面省略。。。
# 逐行读取 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')
data.to_csv(path + '\\data\\ex5_2.csv') # 写出文件到指定目录(windows下,后面要输出的文件名开头必须有个表示路径的'\\',不然不会生成文件,也不报错,很诡异。。。)
data.to_csv(sys.stdout, sep='|') # 以竖线分隔
data.to_csv(sys.stdout, na_rep='NULL') # 以NULL填充na值
data.to_csv(sys.stdout, index=False, header=False) # 不选取索引名和列名
data.to_csv(sys.stdout, index=False, columns=['a', 'b', 'c']) # 重新设置列名
# 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)
# parse_dates 指定某些列是否被解析为日期,布尔值或列表
data2 = pd.read_csv(path + '\\data\\tseries.csv', header=None, parse_dates=True)
# 在IPython界面输入 cd $path命令即可进入path变量所指定的目录下
f = open('ex7.csv')
reader = csv.reader(f)
for line in reader:
print(line)
# 转换成列表
lines = list(csv.reader(open('ex7.csv')))
header, values = lines[0], lines[1:]
# 先将values解压为元组,再与header合并,组成字典
data_dict = {h: v for h,v in zip(header, zip(*values))}
class my_dialect(csv.Dialect):
lineterminator = '\n' # 每行结束符
delimiter = ';' # 定义分隔符
quotechar = '"' # 定义给包含特殊字符的数据所添加的符号
quoting = csv.QUOTE_MINIMAL # 仅对包含特殊字符的数据加quotechar中定义的符号
csv.register_dialect('mycsv', my_dialect) # 注册自定义类
with open('mydata.csv', 'w') as f:
writer = csv.writer(f, 'mycsv') # 可使用自定义名称
writer.writerow(('one', 'two', 'three'))
writer.writerow(('1', '2', '3'))
writer.writerow(('4', '\'5', '6'))
writer.writerow(('7', '8', '9'))
# 在mydata.csv文件中加入特殊符号
# 不带dialect的读取:
with open('mydata.csv', 'r') as file_obj:
reader = csv.reader(file_obj)
for row in reader:
print(row)
# 带dialect的读取:
with open('mydata.csv', 'r') as file_obj:
reader = csv.reader(file_obj, dialect='mycsv')
for row in reader:
print(row)
# 转换成DataFrame格式后再存储
my_data = pd.read_table('mydata.csv', sep=';')
my_data.to_csv('mydata2.csv')
# 将数据转储为Excel的xls工作薄 xlwt
wb = xlwt.Workbook()
print(wb) # Workbook类型的对象
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)
ws_2 = wb.add_sheet('second_sheet') # 在wb中再增加一张sheet页ws_2
data = np.arange(1, 65).reshape(8, 8)
print(data)
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文件中
# 生成xlsx工作簿 xlrd
book = xlrd.open_workbook('workbook.xls') # 读取刚才生成的工作簿文件
print(book) # Book对象
# 常用方法
book.nsheets # 查看sheet总页数
book.sheet_names() # 查看所有的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) # 总行数
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)
print(sheet_2.row(1)) # 获取第1行的数据
result = [number.value for number in sheet_2.row(1)]# 通过.value获取实际值
print(result)
print(sheet_2.row_values(1)) # 直接返回包含实际值的列表,省去了上面的转换过程
print(sheet_2.row_types(0)) # 返回第0行的数据类型列表(对应关系同ctype)
print(sheet_2.col(3)) # 获取第1列的数据
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列的数据
# 逐行打印
for row in range(sheet_1.ncols):
for col in range(sheet_1.nrows):
print(sheet_1.cell(row, col).value)
# 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) # 字典 -> 字符串
siblings = pd.DataFrame(result['siblings'], columns=['name', 'age', 'pet']) # 字典 -> DataFrame
print(siblings)
# 二进制数据格式
# pickle
df = pd.read_csv('ex1.csv')
df.to_pickle('frame_pickle.bin') # DataFrame -> 二进制格式
pickle = pd.read_pickle('frame_pickle.bin') # 二进制 -> DataFrame
# HDF5格式(可压缩格式)
# 使用高性能HD5格式进行数据存储和访问,格式类似字典,适合存储格式统一的分层(hierarchical)数据
# HDF5格式文件的说明:
http://pandas.pydata.org/pandas-docs/stable/io.html#io-hdf5
# pytables doc:
http://www.pytables.org/
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中的数据实际写入本地文件
# 压缩模式(数据量大时较明显)
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()
# 对比文件大小