Linking

Capturing Life & Tech

  • 主页
  • 随笔
  • 关于我
所有文章 外链

Linking

Capturing Life & Tech

  • 主页
  • 随笔
  • 关于我

《利用Python进行数据分析》读书笔记-6-第六章-数据加载、存储和数据格式

阅读数:次 2017-03-25
字数统计: 3.5k字   |   阅读时长≈ 18分

输入输出分类:

  • 读取文本文件
  • 其他更高效的磁盘存储格式
  • 加载数据库中数据
  • 利用Web API操作网络资源

读取文本格式的数据

pandas提供了将表格数据读取为DataFrame对象的函数;其中read_csv和read_table是应用最多的两个:

函数 说明
read_csv 从文件、URL、文件型对象中加载带分隔符的数据;默认逗号
read_table 从文件、URL、文件型对象中加载带分隔符的数据;默认制表符”\t”

类型推断是这些函数中最重要的功能之一。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ cat ex1.csv
<!--out: -->
<!--a,b,c,d,message-->
<!--0,1,2,3,4,hello-->
<!--1,5,6,7,8,world-->
<!--2,9,10,11,12,foo-->
#以上数据用逗号隔开

import pandas as pd
import numpy as np
from pandas import Series, DataFrame

df = pd.read_csv('../pydata-book-master/ch06/ex1.csv')
# print df
# a b c d message
# 0 1 2 3 4 hello
# 1 5 6 7 8 world
# 2 9 10 11 12 foo
pt = pd.read_table('../pydata-book-master/ch06/ex1.csv', sep=',')
# print pt
# out: 同上

对于没有标题行的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ cat ex2.csv
<!--out: -->
<!--0,1,2,3,4,hello-->
<!--1,5,6,7,8,world-->
<!--2,9,10,11,12,foo-->

# 自动分配默认列名

# pc = pd.read_csv('../pydata-book-master/ch06/ex2.csv', header=None)
# print pc
# 0 1 2 3 4
# 0 1 2 3 4 hello
# 1 5 6 7 8 world
# 2 9 10 11 12 foo
# 手动定义列名
# pc2 = pd.read_csv('../pydata-book-master/ch06/ex2.csv', names=['a','b','c','d','msg'])
# print pc2
# a b c d msg
# 0 1 2 3 4 hello
# 1 5 6 7 8 world
# 2 9 10 11 12 foo

指定索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 指定索引
names = ['a','b','c','d','msg']
pc3 = pd.read_csv('../pydata-book-master/ch06/ex2.csv', names=names, index_col='msg')
# print pc3
# a b c d
# msg
# hello 1 2 3 4
# world 5 6 7 8
# foo 9 10 11 12
# 层次化索引
parsed = pd.read_csv('../pydata-book-master/ch06/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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 非固定分隔符,需要正则表达式
# print list(open('../pydata-book-master/ch06/ex3.csv'))
# [' 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']
# 观察到该文件各个字段由不定数量的空白符分割,用`\s+`这个正则来表示:
result = pd.read_table('../pydata-book-master/ch06/ex3.csv', 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

跳过异常行(使用参数skiprows)

1
2
3
4
5
6
7
8
$ 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%

可以认为1,3,4行为异常数据

1
2
3
4
5
print pd.read_csv('../pydata-book-master/ch06/ex4.csv', skiprows=[0,2,3])
# a b c d message
# 0 1 2 3 4 hello
# 1 5 6 7 8 world
# 2 9 10 11 12 foo

逐块读取文本文件

大文件只想读取一小部分或者逐块对文件进行迭代

1
2
3
4
5
6
7
8
result = pd.read_csv('../pydata-book-master/ch06/ex6.csv', nrows=5)
# 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

逐块读取;用到chunksize(行数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# chunker = pd.read_csv('../pydata-book-master/ch06/ex6.csv', chunksize=100)
# print chunker
# <pandas.io.parsers.TextFileReader object at 0x10f6175d0>
# TextFileReader对象可实现盾剑逐块迭代
chunker = pd.read_csv('../pydata-book-master/ch06/ex6.csv', chunksize=1000)
tot = Series([])
for piece in chunker:
tot = tot.add(piece['key'].value_counts(), fill_value=0)
tot = tot.sort_values(ascending=False)
print tot[:10]
# E 368.0
# X 364.0
# L 346.0
# O 343.0
# Q 340.0
# M 338.0
# J 337.0
# F 335.0
# K 334.0
# H 330.0
# dtype: float64

将数据写到文本格式

1
2
3
4
5
6
data = pd.read_csv('../pydata-book-master/ch06/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

pandas.read_csv生成的是DataFrame对象;

DataFrame的to_csv方法,可以将数据写到一个用逗号分隔的文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
data.to_csv('./ch06_out.csv')
# $ cat ./ch06_out.csv
# ,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

# 可以指定分隔符,如|;这里只为了展示,所以用sys.stdout直接打印出来了。
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

将缺失值替换为其他标记值

1
2
3
4
5
data.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

只输出特定列,指定顺序

1
2
3
4
5
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也有to_csv()方法

1
2
3
4
5
6
7
8
9
10
datas = pd.date_range('1/1/2000', periods=7)
ts = Series(np.arange(7), index=datas)
ts.to_csv('./ch06tsseries.csv')
# 2000-01-01,0
# 2000-01-02,1
# 2000-01-03,2
# 2000-01-04,3
# 2000-01-05,4
# 2000-01-06,5
# 2000-01-07,6

更简单的读取方法from_csv

1
2
3
4
5
6
7
8
9
# print Series.from_csv('./ch06tsseries.csv', parse_dates=True)
# 2000-01-01 0
# 2000-01-02 1
# 2000-01-03 2
# 2000-01-04 3
# 2000-01-05 4
# 2000-01-06 5
# 2000-01-07 6
# dtype: int64

手工处理分隔符格式

场景:pandas.read_table加载表格数据时,由于畸形行导致错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# $ cat ch06/ex7.csv
# "a","b","c"
# "1","2","3"
# "1","2","3","4"

import csv

lines = list(csv.reader(open('../pydata-book-master/ch06/ex7.csv')))
headers, values = lines[0], lines[1:]
data_dict = {h: v for h, v in zip(headers, zip(*values))}
# print data_dict
# {'a': ('1', '1'), 'c': ('3', '3'), 'b': ('2', '2')}

class my_dialect(csv.Dialect):
lineterminator = '\n'
delimiter = ';'
quotechar = '"'
quoting = csv.QUOTE_ALL

# delimiter分隔符指定

f = open('../pydata-book-master/ch06/ex7.csv')
reader = csv.reader(f, dialect=my_dialect)
# print reader
# <_csv.reader object at 0x10a5bb440>
# 以上类的参数也可以单个的传入csv.reader方法

手动写入分隔符文件csv.writer

1
2
3
4
5
6
7
8
9
10
11
with open('mydata.csv', 'w') as fw:
writer = csv.writer(fw, my_dialect)
writer.writerow(("one", "two", "three"))
writer.writerow(('1', '2', '3'))
writer.writerow(('4', '5', '6'))
writer.writerow(('7', '8', '9'))
# out: mydata.csv
# "one";"two";"three"
# "1";"2";"3"
# "4";"5";"6"
# "7";"8";"9"

tip:一些东西还是要看源码才最直接

JSON数据

JSON已成为HTTP请求在Web浏览器和其他程序之间发送数据的标准格式之一、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
obj1 = """
{"name": "Wes",
"places_lived": ["United States", "Spain", "Germany"],
"pet":null,
"siblings":[{"name":"Scott", "age":25, "pet":"Zuko"}, {"name":"Katie", "age":22, "pet":"Cisco"}]
}
"""
import json
# json.loads将JSON字符串转换成Python形式
result = json.loads(obj1)
# print result
# {u'pet': None,
# u'siblings': [{u'pet': u'Zuko', u'age': 25, u'name': u'Scott'},
# {u'pet': u'Cisco', u'age': 22, u'name': u'Katie'}],
# u'name': u'Wes',
# u'places_lived': [u'United States', u'Spain', u'Germany']}
# 对应的,json.dumps将Python转换成JSON形式
asjson = json.dumps(result)
# print asjson
# {"pet": null, "siblings": [{"pet": "Zuko", "age": 25, "name": "Scott"},
# {"pet": "Cisco", "age": 22, "name": "Katie"}],
# "name": "Wes", "places_lived": ["United States", "Spain", "Germany"]}

XML和HTML:Web信息收集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# http://finance.yahoo.com/quote/AAPL/options?ltr=1
from lxml.html import parse
from urllib2 import urlopen
# 原网址404,在雅虎随便找了一个阿里巴巴的
# parsed = parse(urlopen('http://finance.yahoo.com/quote/BABA/options?p=BABA'))
# doc = parsed.getroot()
# 通过上面的对象,可获取特定的tag
# 如获取所有的链接;<a href="#">word</a>
# links = doc.findall('.//a')
# print links[:5]
# [<Element a at 0x1109ace10>,
# <Element a at 0x1109ace68>,
# <Element a at 0x1109acec0>,
# <Element a at 0x1109acf18>,
# <Element a at 0x1109acf70>]
# lnk = links[7]
# print lnk
# <Element a at 0x1040d3628>
# 从以上对象中提取出href
# print len(links)
# 50个
# print lnk.get('href')
# https://www.yahoo.com/celebrity/
# print lnk.text_content()
# Celebrity

# 构建列表推导式,获取全部URL
# urls = [lnk1.get('href') for lnk1 in doc.findall('.//a')]
# print urls[-10:]
# ['//finance.yahoo.com/broker-comparison?bypass=true',
# 'https://help.yahoo.com/kb/index?page=content&y=PROD_MAIL_ML&locale=en_US&id=SLN2310&actp=productlink',
# 'http://help.yahoo.com/l/us/yahoo/finance/',
# 'https://yahoo.uservoice.com/forums/382977',
# 'http://info.yahoo.com/privacy/us/yahoo/',
# 'http://info.yahoo.com/relevantads/',
# 'http://info.yahoo.com/legal/us/yahoo/utos/utos-173.html',
# 'http://twitter.com/YahooFinance',
# 'http://facebook.com/yahoofinance',
# 'http://yahoofinance.tumblr.com']

# 从文档中找出正确的表格就是反复试验
# parsed1 = parse(urlopen('http://finance.yahoo.com/quote/BABA/options?p=BABA'))
# doc1 = parsed1.getroot()
# tables = doc1.findall('.//table')
# calls = tables[0]
# puts = tables[0]
# rows = calls.findall('.//tr')
# print rows[0].text_content()
# Search
# def unpack(row, kind='td'):
# elts = row.findall('.//%s' % kind)
# return [val.text_content() for val in elts]

# print unpack(rows[0], kind='th')
# 由于对Safari怎么获取XPath不熟悉,后期还要专门了解
# 原网址变动,书本代码无法运行,需要深入理解改写一下
# 完全照着书本敲收效甚微

# 利用lxml.objectify解析XML
from lxml import objectify
path = '../pydata-book-master/ch06/mta_perf/Performance_MNR.xml'
parsed2 = objectify.parse(open(path))
root = parsed2.getroot()
print root

利用lxml.objectify解析XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from lxml import objectify
# path = '../pydata-book-master/ch06/mta_perf/Performance_MNR.xml'
# parsed2 = objectify.parse(open(path))
# root = parsed2.getroot()
# print root

# 解析HTML标签
from StringIO import StringIO
tag = '<a href="http://www.google.com">Google</a>'
root = objectify.parse(StringIO(tag)).getroot()
# print root.get('href')
# http://www.google.com
# print root.text
# Google

二进制数据格式

1
2
3
4
5
6
7
8
9
# 保存到磁盘上
frame = pd.read_csv('../pydata-book-master/ch06/ex1.csv')
# print frame
# a b c d message
# 0 1 2 3 4 hello
# 1 5 6 7 8 world
# 2 9 10 11 12 foo
# 从磁盘读取到Python对象中
print pd.load('../pydata-book-master/ch06/frame_pickle')

读取Microsoft Excel文件(pandas的ExcelFile类)

1
2
3
4
5
6
7
8
xls_file = pd.ExcelFile('../pydata-book-master/ch06/ex1.xlsx')
# 将某个工作表中的数据通过parse读取到DataFrame中
table = xls_file.parse('Sheet1')
# print table
# a b c d message
# 0 1 2 3 4 hello
# 1 5 6 7 8 world
# 2 9 10 11 12 foo

使用HTML和Web API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
url = 'https://www.google.com.hk/search?safe=strict&site=&source=hp&q=test&btnK=Google+搜索'
resp = requests.get(url)
# print resp
# <Response [200]>
# Web API一般返回JSON字符串
import json
data = json.loads(resp.text)
# print data.keys()
# ValueError: No JSON object could be decoded
# 书上的Twitter链接打不开

# 取出感兴趣的tweet字段,然后将results列表传给DataFrame
tweet_field = ['created_at', 'from_user', 'id', 'text']
tweets = DataFrame(data['result'], columns=tweet_field)
# print tweets
# DataFrame中每一行有了来自一条tweet的数据
tweets._ix[7]

使用数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 数据库选择标准:性能、数据完整性、应用程序的伸缩性需求
# 引入Python内置的sqlite3驱动器
import sqlite3
query = """
CREATE TABLE test (a VARCHAR(20), b VARCHAR(20),
c REAL, d INTEGER
);"""
con = sqlite3.connect(':memory:')
con.execute(query)
con.commit()
# 插入几条数据
data = [('Atlanta', 'Georgia', 1.25, 6),
('Wangjiang', 'Maoan', 2.5, 5),
('Hefei', 'Gaoxing', 5.5, 9)]
stmt = "INSERT INTO test VALUES(?,?,?,?)"
con.executemany(stmt, data)
con.commit()
# 从表中选取数据
cursor = con.execute('select * from test')
rows = cursor.fetchall()
# print rows
# [(u'Atlanta', u'Georgia', 1.25, 6),
(u'Wangjiang', u'Maoan', 2.5, 5),
(u'Hefei', u'Gaoxing', 5.5, 9)]
# 列名位于游标的description属性中
# print cursor.description
# (('a', None, None, None, None, None, None),
# ('b', None, None, None, None, None, None),
# ('c', None, None, None, None, None, None),
# ('d', None, None, None, None, None, None))
# 传入DataFrame
# print DataFrame(rows, columns=zip(*cursor.description)[0])
# a b c d
# 0 Atlanta Georgia 1.25 6
# 1 Wangjiang Maoan 2.50 5
# 2 Hefei Gaoxing 5.50 9

# pandas有一个简化过程的read_frame函数
import pandas.io.sql as sql
# 书本上read_frame已失效
# print sql.read_sql('select * from test', con)
# a b c d
# 0 Atlanta Georgia 1.25 6
# 1 Wangjiang Maoan 2.50 5
# 2 Hefei Gaoxing 5.50 9

存取MongoDB数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 电脑上需要装MongoDB数据库;
# 使用pymongo驱动通过默认端口连接
# 存储在MongoDB中的文档被组织在数据库的集合(想象成表)
# 没有装,姑且记录一下该怎么写,留作参考
import pymongo
con = pymongo.Connection('localhost', port=27017)
# MongoDB服务运行的每个实例可以有多个数据库,每个数据库又可以有多个集合。
# 访问之前获取的tweets集合
tweets = con.db.tweets
# 加载数据并存入集合
import requests, json

url = 'https://www.google.com.hk/search?safe=strict&site=&source=hp&q=test&btnK=Google+搜索'
data = json.loads(requests.get(url).text)
for tweet in data['results']:
tweets.save(tweet)

# 从集合中取出
cursor = tweets.find({'from_user': 'linking'})
# 转换成DataFrame
tweet_fileds = ['create_at', 'from_user', 'id', 'text']
result = DataFrame(list(cursor), columns=tweet_fileds)

走过了一遍第六章,给我的感觉是,工具很强大,可以做很多数据分析工作,数据结构知识还是匮乏,一些比较复杂的东西还是不能很好的理解,需要加强,多看几遍也是一个方法。

时间上,下班时间有点晚,可以看书的时间都在9点左右,有点晚,太累了,以后下班是不是可以早一点,做饭时间吃饭时间太晚;另外严重缺乏锻炼了,涨了一些肉的,膝盖还是没有恢复,需要针对性锻炼。

记一下,博客的评论插件,多说社会化评论系统已经关闭;选择移除多说或者换成其他的。

………………………………………………2017-03-25 22:57 Sat&合肥-皖水公寓

  • 本文作者: Linking
  • 本文链接: https://linking.fun/2017/03/25/《利用Python进行数据分析》读书笔记-6-第六章-数据加载、存储和数据格式/
  • 版权声明: 版权所有,转载请注明出处!
  • python
  • cs

扫一扫,分享到微信

ListView嵌套GridView显示多张图片出现图片重复、错乱、闪烁等问题
《利用Python进行数据分析》读书笔记-第五章-pandas入门
  1. 1. 读取文本格式的数据
  2. 2. 逐块读取文本文件
  3. 3. 将数据写到文本格式
  4. 4. 手工处理分隔符格式
  5. 5. JSON数据
  6. 6. XML和HTML:Web信息收集
  7. 7. 利用lxml.objectify解析XML
  8. 8. 二进制数据格式
  9. 9. 读取Microsoft Excel文件(pandas的ExcelFile类)
  10. 10. 使用HTML和Web API
  11. 11. 使用数据库
  12. 12. 存取MongoDB数据
© 2015-2026 Linking
GitHub:hexo-theme-yilia-plus by Litten
本站总访问量次 | 本站访客数人
  • 所有文章
  • 外链

tag:

  • weather
  • 需求
  • essay
  • basketball
  • olympic
  • nginx
  • APPScan
  • SQl盲注
  • xss
  • Ajax
  • ajax
  • ai
  • agent
  • openclaw
  • ccf
  • Nginx
  • HTML5
  • html5
  • hmtl5
  • sse
  • JavaScriptCore
  • Oracle
  • operation
  • Linux
  • deploy
  • Mac Office
  • markdown
  • ListView
  • GridView
  • MySQL
  • 慢查询
  • mongodb
  • 转置
  • thought
  • network
  • ubuntu
  • NetworkManager
  • RFKill
  • Netplan
  • avatar
  • cocoa
  • blog
  • Gitalk
  • container
  • macvlan
  • docker
  • oracle
  • cookie
  • patch
  • gitea
  • git
  • iOS
  • https
  • 多线程
  • bundle
  • 兼容性
  • HTTP
  • 绘图
  • cs
  • java
  • 效率
  • 快捷键
  • route
  • nodejs
  • pip
  • arcgis
  • arcgis 建模
  • 标识
  • redis
  • read
  • bookList
  • running
  • showdoc
  • disk
  • unit-test
  • D.Wade
  • thoughts
  • duoduo
  • Python
  • python
  • tomcat
  • 读书节
  • session
  • jdk
  • war
  • 加班
  • Android onclick事件监听
  • 正则
  • 手机品牌匹配
  • ntp
  • OpenLayers
  • Geoserver
  • wechat
  • 微信公众号
  • 爬虫
  • WeChat
  • 张靓颖
  • 动漫
  • vpn
  • PPT
  • MarkDown
  • plan
  • 朱赟
  • 极客时间专栏
  • 极客邦
  • 模块化
  • MVC
  • excel
  • NBA
  • kobe
  • team
  • crawler
  • 进度条
  • ssl
  • book
  • anti-stealing-link
  • Agentic Engineering
  • Vibe Coding
  • Software 3.0
  • Andrej Karpathy
  • LLM
  • Programming

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia-plus根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • GitHub Trending
  • OpenAI ChatGPT
  • Gitee码云
  • 简书
  • CSDN