《python数据分析(第2版)-阿曼多.凡丹戈》读书笔记第8章-应用数据库

python数据分析我的学习读书笔记-目录索引 html

第8章应用数据库python

   本章中,咱们将为读者介绍各类数据库及其应用编程接口。这里所说的数据库包括关系型数据库以及非关系型(NoSQL)数据库。关系型数据库是由数据表聚集而成的,更重要的是,这些数据表中的数据是按照数据项之间的关系进行组织的。固然,这里所说的关系,也能够是某个数据表中的行数据与其余数据表中的行数据之间的关系。关系型数据库不只涉及数据表之间的关系,首先,它要处理同一个数据表中不一样列之间的关系(很明显,一个数据表内的各列毫无疑问是相关的);其次,它还要处理数据表之间的关系。redis

  伴随着大数据和Web应用的流行,非关系型(Not Only SQL,NoSQL)数据库也开始野蛮生长。NoSQL系统将成为类SQL事实上的标准。NoSQL数据库的主旨在于,使用比关系模型更为灵活的方式来存储数据。这就可能意味着,无需数据库模式或者灵活的数据库模式。固然,灵活性和速度也是有代价的,例如没法始终保证事务的一致性。NoSQL数据库能够利用面向列的方法以字典的形式来储存数据,这些数据对象包括文档、对象、图、元组,甚至这些对象的组合体。本章将要介绍的主题以下。sql

  • 基于sqlite3的轻量级访问
  • 经过Pandas访问数据库
  • SQLAlchemy
  • Pony ORM
  • Dataset:懒人数据库
  • PyMongo与MongoDB
  • 利用Redis存储数据
  • 利用memcache存储数据
  • Apache Cassandra。

 

8.1基于sqlite3的轻量级访问数据库

   SQLite是一款很是流行的关系型数据库,它很是轻盈,所以被大量应用程序普遍采纳,如Mozilla Firefox等浏览器。安卓系统上的大部分应用的数据存储也是经过SQLite完成的。编程

  Sqlite3是Python标准发行版自带的一个模块,能够用于处理SQLite数据库。使用sqlite3模块时,数据库既能够存放到文件中,也能够保留在内存中。本例采用后一种方式。下面咱们导入sqlite3,代码以下。json

import sqlite3

  首先,链接数据库。若是但愿把数据库存到文件中,那么必须提供一个文件名,不然,能够经过下列方式将数据库留在内存中。设计模式

with sqlite3.connect(":memory:") as con:

  上面使用了Python的with语句。须要注意的是,这个语句依赖于特定上下文管理器类的exit()方法的存在。若是使用了这个语句,咱们就无需显式关闭数据库链接了。这是由于上下文管理器会自动替咱们关闭链接。链接到数据库后,咱们还须要一个游标。游标在数据库中的做用,至少从概念上来说,相似于文本编辑器中的光标。注意,这个游标也须要由咱们来关闭。api

  下面开始建立游标,代码以下。浏览器

c = con.cursor()

  如今,能够直接建立数据表了。一般,必须首先建立一个数据库,或数据库专家已经替咱们创建了一个数据库。在本章中,咱们不只须要了解Python,并且还得懂SQL。SQL是一种专门用来查询和操做数据库的语言。限于篇幅,这里不可能对SQL进行详尽地介绍。不过,只要稍微努力,读者就可以掌握基本的SQL。为了建立数据表,咱们须要向游标传递一个SQL字符串,具体以下。

 c.execute('''CREATE TABLE sensors (date text, city text, code text, sensor_id real, temperature real)''')

  上面的代码会建立一个包含不少列的数据表,具体名称为sensors。在上面的字符串中,text和real用来代表字符串和数值的类型。经过上面的代码,咱们就能建立一个可用的数据表了。若是建立过程发生错误,咱们就会收到相应的出错提示。列出数据库中数据表的方法与数据库自己紧密相关。一般,有一个或一组专门的数据表来存放用户数据表的元数据。下面咱们列出SQLite数据表,具体以下。

   for table in c.execute("SELECT name FROM sqlite_master WHERE type = 'table'"):
        print("Table", table[0])

  正如所料,咱们将获得以下的输出。

Table sensors

  如今,咱们要插入并查询一些随机数据,具体以下。

1     c.execute("INSERT INTO sensors VALUES ('2016-11-05','Utrecht','Red',42,15.14)")
2     c.execute("SELECT * FROM sensors")
3     print(c.fetchone())

  下面咱们输出插入的记录。

(u’2016-11-05’, u’Utrecht’, u’Red’, 42.0, 15.14)

  当再也不须要某个数据表时,咱们就能够将其删除了。须要注意的是,删除是一项很是危险的操做,所以,咱们必须绝对确定再也用不到这个数据表了。由于数据表一旦被删,就没法恢复了,除非以前已经作好了备份。下面的代码将删除数据表并显示删除操做执行后所剩数据表的数量,具体以下。

1     con.execute("DROP TABLE sensors")
2     print("# of tables", c.execute("SELECT COUNT(*) FROM sqlite_master WHERE type = 'table'").fetchone()[0])

输出内容以下。

# of tables 0

  下列代码摘自本书代码包中的ch-08.ipynb文件。

 1 import sqlite3
 2 
 3 with sqlite3.connect(":memory:") as con:
 4     c = con.cursor()
 5     c.execute('''CREATE TABLE sensors (date text, city text, code text, sensor_id real, temperature real)''')
 6 
 7     for table in c.execute("SELECT name FROM sqlite_master WHERE type = 'table'"):
 8         print("Table", table[0])
 9 
10     c.execute("INSERT INTO sensors VALUES ('2016-11-05','Utrecht','Red',42,15.14)")
11     c.execute("SELECT * FROM sensors")
12     print(c.fetchone())
13     con.execute("DROP TABLE sensors")
14 
15     print("# of tables", c.execute("SELECT COUNT(*) FROM sqlite_master WHERE type = 'table'").fetchone()[0])
16 
17     c.close()

8.2经过Pandas访问数据库

   咱们能够向Pandas提供一个数据库链接,如前面例子中的链接或SQLAlchemy链接。关于SQLAlchemy链接,咱们将在本章后面部分进行讲解。正如第7章所述,这里也要用到statsmodels模块的太阳黑子活动数据。为了加载数据,咱们可使用下列代码。

  (1)建立元组列表,以构建Pandas DataFrame。

rows = [tuple(x) for x in df.values]

  与以前的示例不一样,这里要建立的是一个未规定数据类型的数据表,代码以下。

con.execute("CREATE TABLE sunspots(year, sunactivity)")

  (2)咱们知道,executemany()方法能够执行多条语句。就本例而言,咱们要插入一些记录,这些记录来自元组列表。下面将这些数据行插入数据表并显示行数。

1    con.executemany("INSERT INTO sunspots(year, sunactivity) VALUES (?, ?)", rows)
2    c.execute("SELECT COUNT(*) FROM sunspots")
3    print(c.fetchone())

  数据表的行数以下。

(309,)

  (3)execute()函数返回结果中rowcount属性存放的是受影响的数据行的数量。这个属性有点古怪,并且与SQLite版本密切相关。另外,就像上面代码中看到的那样,SQL查询是无歧义的。下面咱们删除事件数大于20的记录,代码以下。

    print("Deleted", con.execute("DELETE FROM sunspots where sunactivity > 20").rowcount, "rows")

  结果以下。

Deleted 217 rows

  (4)若是把数据库链接至Pandas,就能够利用read_sql()函数来执行查询并返回Pandas DataFrame了。下面选择前1732条记录,代码以下。

  print(read_sql("SELECT * FROM sunspots where year < 1732", con))

  最终获得以下Pandas DataFrame。

      year  sunactivity
0   1700.0          5.0
1   1701.0         11.0
2   1702.0         16.0
3   1707.0         20.0
4   1708.0         10.0
5   1709.0          8.0
6   1710.0          3.0
7   1711.0          0.0
8   1712.0          0.0
9   1713.0          2.0
10  1714.0         11.0
11  1723.0         11.0

  如下代码摘自本书代码包中的ch-08.ipynb文件。

 1 import statsmodels.api as sm
 2 from pandas.io.sql import read_sql
 3 import sqlite3
 4 
 5 with sqlite3.connect(":memory:") as con:
 6     c = con.cursor()
 7 
 8     data_loader = sm.datasets.sunspots.load_pandas()
 9     df = data_loader.data
10     rows = [tuple(x) for x in df.values]
11 
12     con.execute("CREATE TABLE sunspots(year, sunactivity)")
13     con.executemany("INSERT INTO sunspots(year, sunactivity) VALUES (?, ?)", rows)
14     c.execute("SELECT COUNT(*) FROM sunspots")
15     print(c.fetchone())
16     print("Deleted", con.execute("DELETE FROM sunspots where sunactivity > 20").rowcount, "rows")
17 
18     print(read_sql("SELECT * FROM sunspots where year < 1732", con))
19     con.execute("DROP TABLE sunspots")
20 
21     c.close() 

8.3SQLAlchemy

   SQLAlchemy以基于设计模式(design pattern)的对象关系映射(ORM)而闻名。也就是说,它能够把Python的类映射为数据库的数据表。实际上,这意味着添加了一个额外的抽象层,所以,咱们须要使用SQLAlchemy应用程序接口来跟数据库打交道,而非使用SQL命令。使用SQLAlchemy的好处是,它可以在幕后替咱们处理各类细节。不过,凡事有利皆有弊,使用SQLAlchemy的缺点是咱们不得不学习其应用程序接口,同时,性能也会有所降低。本节将学习如何安装SQLAlchemy以及如何经过SQLAlchemy填充和查询数据库。

8.3.1 SQLAlchemy的安装和配置

   下面是安装SQLAlchemy所需的命令。

$ pip3 install sqlalchemy

  在编写本书时,SQLAlchemy的最新版本是1.3.15。从其官网能够找到SQLAlchemy的安装程序和代码仓库。

此外,SQLAlchemy还有一个支持页面,在使用SQLAlchemy的时候,须要定义一个超类,代码以下。

1 from sqlalchemy.ext.declarative import declarative_base
2 Base = declarative_base()

  本节及后面几节中会使用一个带有两个数据表的小型数据库,其中第1个数据表是关于观测站的,第2个数据表是描述观测站内的传感器的。每一个观测站能够有0个、1个或者多个传感器,其中,每一个观测站都有一个整数ID,这些数字是由数据库自动生成的。此外,每一个观测站都有一个名称,并且这个名称是惟一的,也是强制性的。

  同时,每一个传感器也有本身的整数ID。咱们将记录传感器的最后一次观察值。这个值能够是观测值的倍数。具体状况读者能够参考本书代码包中的ch-08.ipynb代码。注意,咱们没必要直接运行这个脚本,由于它是供其余脚本使用的。

 1 from sqlalchemy import Column, ForeignKey, Integer, String, Float
 2 from sqlalchemy.ext.declarative import declarative_base
 3 from sqlalchemy.orm import relationship
 4 from sqlalchemy import create_engine
 5 from sqlalchemy import UniqueConstraint
 6 
 7 Base = declarative_base()
 8 class Station(Base):
 9     __tablename__ = 'station'
10     id = Column(Integer, primary_key=True)
11     name = Column(String(14), nullable=False, unique=True)
12 
13     def __repr__(self):
14         return "Id=%d name=%s" %(self.id, self.name)
15 
16 class Sensor(Base):
17     __tablename__ = 'sensor'
18     id = Column(Integer, primary_key=True)
19     last = Column(Integer)
20     multiplier = Column(Float)
21     station_id = Column(Integer, ForeignKey('station.id'))
22     station = relationship(Station)
23 
24     def __repr__(self):
25         return "Id=%d last=%d multiplier=%.1f station_id=%d" 
26 # %(self.id, self.last, self.multiplier, self.station_id)
27 
28 if __name__ == "__main__":
29     print("This script is used by code further down in this notebook.")

8.3.2 经过SQLAlchemy填充数据库

   数据表的建立将在后面介绍。本节先来准备一个脚本,以便用来填充数据库(注意,不用直接运行这个脚本,由于它是供8.3.3节中的脚本使用的)。经过DBSession对象,能够向数据表中插入数据。固然,咱们还须要一个引擎,不过,引擎的建立方法也留到8.3.3节介绍。

  1. 建立DBSession对象,代码以下。

1     Base.metadata.bind = engine
2 
3     DBSession = sessionmaker(bind=engine)
4     session = DBSession()

  2. 建立两个观测站。

1     de_bilt = Station(name='De Bilt')
2     session.add(de_bilt)
3     session.add(Station(name='Utrecht'))
4     session.commit()
5     print("Station", de_bilt)

  在提交这个会话前,这些数据行是不会被插入的。下面是与第一个观测站有关的输出。

Station Id=1 name=De Bilt

 

  3.一样,还要插入传感器记录,代码以下。

1     temp_sensor = Sensor(last=20, multiplier=.1, station=de_bilt)
2     session.add(temp_sensor)
3     session.commit()
4     print("Sensor", temp_sensor)

  这个传感器位于第一个观察站中,因此,将获得以下输出内容。

Sensor Id=1 last=20 multiplier=0.1 station_id=1

  数据库填充代码能够在本书代码包中的ch-08.ipynb文件中找到。一样,这个脚本也无需直接运行,它也是供其余脚本使用的。填充代码以下。

 1 from sqlalchemy import create_engine
 2 from sqlalchemy.orm import sessionmaker
 3 
 4 #from alchemy_entities import Base, Sensor, Station
 5 
 6 def populate(engine):
 7     Base.metadata.bind = engine
 8 
 9     DBSession = sessionmaker(bind=engine)
10     session = DBSession()
11 
12     de_bilt = Station(name='De Bilt')
13     session.add(de_bilt)
14     session.add(Station(name='Utrecht'))
15     session.commit()
16     print("Station", de_bilt)
17 
18     temp_sensor = Sensor(last=20, multiplier=.1, station=de_bilt)
19     session.add(temp_sensor)
20     session.commit()
21     print("Sensor", temp_sensor)
22 
23 if __name__ == "__main__":
24     print("This script is used by code further down in this notebook")

8.3.3 经过SQLAlchemy查询数据库

   下面经过URI来建立引擎,代码以下。

1 engine = create_engine('sqlite:///demo.db')

  经过这个URI,咱们规定要使用的引擎为SQLite,同时指出要把数据存放到文件demo.db中。而后,利用刚才建立的引擎来建立两个数据表,即station和sensor。相应代码以下。

1 Base.metadata.create_all(engine)

  对于SQLAlchemy查询,咱们也须要一个DBSession对象,这个对象在8.3.2节已经介绍过了。

  下面选择数据表station中的第一行数据。

1 station = session.query(Station).first()

  下面代码用于选择全部观测站,具体以下。

1 print("Query 1", session.query(Station).all())

  下面是输出结果。

Query 1 [Id=1 name=De Bilt, Id=2 name=Utrecht]

  选择全部传感器,代码以下。

1 print("Query 2", session.query(Sensor).all())

  下面是输出结果。

Query 2 [Id=1 last=20 multiplier=0.1 station_id=1]

  下面,选择第一个观测站的第一个传感器,代码以下。

1 print("Query 3", session.query(Sensor).filter(Sensor.station == station).one())

  下面是输出结果。

Query 3 Id=%d last=%d multiplier=%.1f station_id=%d

  还可使用pandas的read_sql()方法进行查询,具体以下。

1 print(read_sql("SELECT * FROM station", engine.raw_connection()))

  输出内容以下。

   id     name
0   1  De Bilt
1   2  Utrecht

  如下代码摘自本书代码包中的ch-08.ipynb文件。

 1 #from alchemy_entities import Base, Sensor, Station
 2 #from populate_db import populate
 3 from sqlalchemy import create_engine
 4 from sqlalchemy.orm import sessionmaker
 5 import os
 6 from pandas.io.sql import read_sql
 7 
 8 
 9 engine = create_engine('sqlite:///demo.db')
10 Base.metadata.create_all(engine)
11 populate(engine)
12 Base.metadata.bind = engine
13 DBSession = sessionmaker()
14 DBSession.bind = engine
15 session = DBSession()
16 
17 station = session.query(Station).first()
18 
19 print("Query 1", session.query(Station).all())
20 print("Query 2", session.query(Sensor).all())
21 print("Query 3", session.query(Sensor).filter(Sensor.station == station).one())
22 print(read_sql("SELECT * FROM station", engine.raw_connection()))
23 
24 try:
25     os.remove('demo.db')
26     print("Deleted demo.db")
27 except OSError:
28     pass

8.4Pony ORM

   Pony ORM是Python编程语言下的另外一款ORM程序包。Pony ORM是用纯Python编写的,它能自动进行查询优化,同时提供了一个图形用户界面的数据库模式编辑器。此外,它还支持自动事务处理、自动缓存和组合关键字(Composite Keys)。有了Pony ORM,咱们就能够经过Python的生成器表达式来查询数据库了。固然,这些生成器最终都会转换为SQL。

  安装这个程序库的命令以下。

1 $ pip3 install pony

  本例中咱们将用到这个程序包,所以须要将其导入。下面的导入代码摘自本书代码包中的pony_ride.py文件。

1 from pony.orm import *
2 # database,db_session
3 import statsmodels.api as sm

  下面咱们来建立一个in-memory型的SQLite数据库。

1 db = Database('sqlite', ':memory:', create_db = True)

  下面经过Pandas的write_frame()函数来加载太阳黑子数据并将其写入数据库。具体代码以下。

1 with db_session:
2     data_loader = sm.datasets.sunspots.load_pandas()
3     df = data_loader.data
4     df.to_sql("sunspots", db.get_connection())
5 
6     print(db.select(" count(*) from sunspots"))

  这个太阳黑子数据表的行数以下。

[309]

 

 8.5Dataset:懒人数据库

  Dataset是一个Python库,实际上就是SQLAlchemy的一个包装器。这个库的开发主旨是尽可能作到易于使用,也就是尽可能让懒人满意。

  安装dataset的命令以下。

$ pip3 install dataset

  建立并链接一个in-memory型的SQLite数据库,代码以下。

1 import dataset
2 
3 db = dataset.connect('sqlite:///:memory:')

  建立一个名为books的数据表,代码以下。

1 table = db["books"]

  事实上,在数据库中这个表还没有建立,由于咱们尚未为其指定任何列。咱们只是建立了一个相关的对象。咱们调用insert()方法时,会自动建立数据表模式,同时,向insert()方法传递含有书名的字典,具体代码以下。

1 table.insert(dict(title="NumPy Beginner's Guide", author='Ivan Idris'))
2 table.insert(dict(title="NumPy Cookbook", author='Ivan Idris'))
3 table.insert(dict(title="Learning NumPy", author='Ivan Idris'))

  经过下列代码,能够显示数据表各行的内容。

1 for row in table.find(_limit=5):
2    print(row)

  结果以下。

   id                   title      author
0   1  NumPy Beginner's Guide  Ivan Idris
1   2          NumPy Cookbook  Ivan Idris
2   3          Learning NumPy  Ivan Idris
OrderedDict([('index', 0), ('YEAR', 1700.0), ('SUNACTIVITY', 5.0)])
OrderedDict([('index', 1), ('YEAR', 1701.0), ('SUNACTIVITY', 11.0)])
OrderedDict([('index', 2), ('YEAR', 1702.0), ('SUNACTIVITY', 16.0)])
OrderedDict([('index', 3), ('YEAR', 1703.0), ('SUNACTIVITY', 23.0)])
OrderedDict([('index', 4), ('YEAR', 1704.0), ('SUNACTIVITY', 36.0)])

  如今,咱们能够轻松显示该数据库中各个数据表了,代码以下。

1 print("Tables", db.tables)

  上述代码的输出结果以下。

Tables ['books', 'sunspots']

  下面的代码摘自本书代码包中的ch-08.ipynb文件。(邀月修正“AttributeError: 'Connection' object has no attribute 'raw_connection'”错误)

 1 import dataset
 2 from pandas.io.sql import read_sql
 3 from pandas.io.sql import to_sql
 4 import statsmodels.api as sm
 5 
 6 db = dataset.connect('sqlite:///:memory:')
 7 table = db["books"]
 8 table.insert(dict(title="NumPy Beginner's Guide", author='Ivan Idris'))
 9 table.insert(dict(title="NumPy Cookbook", author='Ivan Idris'))
10 table.insert(dict(title="Learning NumPy", author='Ivan Idris'))
11 
12 # print(help(db.executable))
13 
14 # print(read_sql('SELECT * FROM books', db.executable.raw_connection()) )
15 # print(read_sql('SELECT * FROM books', db.executable.contextual_connect()) )
16 print(read_sql('SELECT * FROM books', db.engine) )
17 
18 data_loader = sm.datasets.sunspots.load_pandas()
19 df = data_loader.data
20 #write_frame(df, "sunspots", db.executable.raw_connection()) 
21 # df.to_sql("sunspots", db.executable.contextual_connect()) 
22 df.to_sql("sunspots", db.engine) 
23 
24 
25 table = db['sunspots']
26 
27 for row in table.find(_limit=5):
28    print(row)
29 
30 print("Tables", db.tables)

tips:

一、原书中print(read_sql('SELECT * FROM books', db.executable.raw_connection()) )引起AttributeError: 'Connection' object has no attribute 'raw_connection'

二、改用print(read_sql('SELECT * FROM books', db.executable.contextual_connect()) )不报错,但会引起一个警告,大意是:SADeprecationWarning: The Engine.contextual_connect() and Connection.contextual_connect() methods are deprecated.  This method is an artifact of the threadlocal engine strategy which is also to be deprecated.   For explicit connections from an Engine, use the Engine.connect() method

三、最后使用print(read_sql('SELECT * FROM books', db.engine) )正常运行。

邀月工做室

 

邀月工做室

邀月工做室

 

8.6PyMongo与MongoDB

   MongoDB是一个面向文档的NoSQL数据库,其名称取自humongous一词,即硕大无比之意,其中,文档将以相似JSON的BSON格式进行存储。咱们能够下载MongoDB,安装过程很是简单,咱们只需将压缩文件解压便可。创做本书时,这个程序库的版本为3.4.0。这个版本的bin目录下面有一个名为mongod的文件,用来启动服务器。MongoDB位于/data/db目录下面,该目录就是存储数据的地方。固然,能够经过下列命令来指定其余目录。

$ mkdir /tmp/db

  进入存放数据库二进制可执行代码的目录并启动数据库,命令以下。

./mongod –dbpath /tmp/db

  这个进程须要一直运行,这样咱们才能查询数据库。

  PyMongo是MongoDB的Python驱动程序,这个程序的安装方法以下。

1 $ pip3 install pymongo

  与MongoDB的测试数据库创建链接,代码以下。

1 from pymongo import MongoClient
2 
3 client = MongoClient()
4 db = client.test_database

  别忘了,咱们是能够利用pandas DataFrame来建立JSON的。下面建立JSON并将其存于MongoDB中,代码以下。

1 data_loader = sm.datasets.sunspots.load_pandas()
2 df = data_loader.data
3 rows = json.loads(df.T.to_json()).values()
4 db.sunspots.insert_many(rows)

  如今,咱们来查询刚才建立的文档。

1 cursor = db['sunspots'].find({})
2 df =  pd.DataFrame(list(cursor))
3 print(df)

  这将打印输出整个pandas DataFrame。下列代码摘自本书代码包中的ch-08.ipynb文件。

 1 from pymongo import MongoClient
 2 import statsmodels.api as sm
 3 import json
 4 import pandas as pd
 5 
 6 client = MongoClient()
 7 db = client.test_database
 8 
 9 data_loader = sm.datasets.sunspots.load_pandas()
10 df = data_loader.data
11 rows = json.loads(df.T.to_json()).values()
12 db.sunspots.insert_many(rows)
13 
14 cursor = db['sunspots'].find({})
15 df =  pd.DataFrame(list(cursor))
16 print(df)
17 
18 db.drop_collection('sunspots')

  注意:因邀月本机无MongoDB,因此未运行本实例,若有报错,请告知。谢谢!

8.7利用Redis存储数据

  Redis是一个in-memory型的键-值数据库,由C语言编写而成。Redis这个名称源自Remote Dictionary Server,即远程字典服务器。处于内存存储模式时,Redis的速度快得惊人,并且读写操做的速度几乎同样快。Redis遵循发布订阅模式而且经过Lua脚原本处理存储过程。发布订阅模式经过客户端可订阅的信道来接收消息。创做本书时的Redis最新版本为3.2.6,咱们能够下载Redis。完成安装以后,咱们就能够经过如下命令来运行服务器了。

1 $ src/redis-server

  下面开始安装一个Python驱动程序,命令以下。

1 $ pip3 install redis

  Redis的使用很是简便,只要把它看成一个庞大的字典便可。不过,Redis也有自身的局限性。有时,它的易用性仅仅体如今将复杂的对象存储为JSON字符串或其余格式。这正是咱们联合使用Pandas DataFrame的缘由。下面,咱们与Redis创建链接,代码以下。

1 r = redis.StrictRedis()

  经过JSON字符串建立一个键-值对,代码以下。

1 r.set('sunspots', data)

  经过下列代码检索数据。

1 blob = r.get('sunspots')

  下面的代码很是简单,它们摘自本书代码包中的ch-08.ipynb文件。

 1 import redis
 2 import statsmodels.api as sm
 3 import pandas as pd
 4 
 5 r = redis.StrictRedis()
 6 data_loader = sm.datasets.sunspots.load_pandas()
 7 df = data_loader.data
 8 data = df.T.to_json()
 9 r.set('sunspots', data)
10 blob = r.get('sunspots')
11 print(pd.read_json(blob))

 注意:因邀月本机无Redis,因此未运行本实例,若有报错,请告知。谢谢!

 

8.8利用memcache存储数据

   与Redis相似,memcache也是一个in-memory型的键-值数据库。在安装运行memcache服务器以后,就能够经过下列命令来安装memcache的Python客户端了。

1 $ pip3 install python3-memcache

  下面的代码摘自ch-08.ipynb文件,它将建立一个memcache客户端,而后将DataFrame存储到Memcache,其中自动过时值为600秒。这段代码与前面介绍Redis时看到的代码很是类似。

 1 import memcache
 2 import statsmodels.api as sm
 3 import pandas as pd
 4 
 5 client = memcache.Client([('127.0.0.1', 11211)])
 6 data_loader = sm.datasets.sunspots.load_pandas()
 7 df = data_loader.data
 8 data = df.T.to_json()
 9 client.set('sunspots', data, time=600)
10 print("Stored data to memcached, auto-expire after 600 seconds")
11 blob = client.get('sunspots')
12 print(pd.read_json(blob))

 注意:因邀月本机无memcache,因此未运行本实例,若有报错,请告知。谢谢!

 

8.9Apache Cassandra

   Apache Cassandra是结合了键-值和传统关系型数据库特性的混合型数据库。对于传统的关系型数据库而言,数据表中的列是固定的。但是,对于Cassandra来讲,同一个数据表中的各行能够具备不一样的列。从这个角度看,Cassandra是一种面向列的数据库,由于它容许各行灵活使用不一样的模式。这个数据库中的各列,都是按照所谓的列族(Column Family)进行组织的,这里的列族至关于关系型数据库中的数据表。Cassandra数据库已经摒弃了各类链接和子查询操做。读者能够自行下载Cassandra。在本书写做时,这个数据库的最新版本是3.9。

  (1)     从命令行运行服务器,命令以下。

1  $ bin/cassandra-f

  (2)能够建立conf/cassandra.yaml中列出的目录,或者进行以下的调整。

1 data_file_directories:/tmp/lib/cassandra/data
2 commitlog_directory: /tmp/lib/cassandra/commitlog
3 saved_caches_directory: /tmp/lib/cassandra/saved_caches

  (3)若是不想保存某些数据,能够考虑下列命令。

1 $ mkdir -p /tmp/lib/cassandra/data
2 $ mkdir -p /tmp/lib/cassandra/commitlog
3 $ mkdir -p /tmp/lib/cassandra/saved_caches

  (4)下面安装Python驱动程序,命令以下。

1  $ pip3 install cassandra-driver

  (5)下面开始编写代码。首先,与集群创建链接并建立一个会话,代码以下。

1 cluster = Cluster()
2 session = cluster.connect()

  (6)在Cassandra中,有一个所谓的keyspace的概念,它实际上就是用来存放数据表的一个容器。Cassandra创建了本身的查询语言,名为Cassandra查询语言(Cassandra Query Language,CQL)。CQL的用法与SQL相似。下面建立keyspace并设置使用该keyspace的会话,代码以下。

1 session.execute("CREATE KEYSPACE IF NOT EXISTS mykeyspace WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };")
2 session.set_keyspace('mykeyspace')

  (7)如今,建立一个数据表来存放太阳黑子数据,代码以下。

1 session.execute("CREATE TABLE IF NOT EXISTS sunspots (year decimal PRIMARY KEY, sunactivity decimal);")

  (8)建立一条语句,该语句将在循环语句中把元组做为数据行来插入,代码以下。

1 query = SimpleStatement(
2     "INSERT INTO sunspots (year, sunactivity) VALUES (%s, %s)",
3     consistency_level=ConsistencyLevel.QUORUM)

  (9)下列代码用于插入数据。

1 for row in rows:
2     session.execute(query, row)

  (10)取得数据表中数据的行数。

1 rows=session.execute("SELECT COUNT(*) FROM sunspots")
2 for row in rows:
3     print(row)

  输出的行数以下。

[Row(count=309)]

  (11)删除keyspace,关闭集群。

1 session.execute('DROP KEYSPACE mykeyspace') 
2 cluster.shutdown()

  下列代码摘自本书代码包中的ch-08.ipynb文件。

 1 from cassandra import ConsistencyLevel
 2 from cassandra.cluster import Cluster
 3 from cassandra.query import SimpleStatement
 4 import statsmodels.api as sm
 5 
 6 cluster = Cluster()
 7 session = cluster.connect()
 8 session.execute("CREATE KEYSPACE IF NOT EXISTS mykeyspace WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };")
 9 session.set_keyspace('mykeyspace')
10 session.execute("CREATE TABLE IF NOT EXISTS sunspots (year decimal PRIMARY KEY, sunactivity decimal);")
11 
12 query = SimpleStatement(
13     "INSERT INTO sunspots (year, sunactivity) VALUES (%s, %s)",
14     consistency_level=ConsistencyLevel.QUORUM)
15 
16 data_loader = sm.datasets.sunspots.load_pandas()
17 df = data_loader.data
18 rows = [tuple(x) for x in df.values]
19 for row in rows:
20     session.execute(query, row)
21 
22 rows=session.execute("SELECT COUNT(*) FROM sunspots")
23 for row in rows:
24     print(row)
25 
26 session.execute('DROP KEYSPACE mykeyspace') 
27 cluster.shutdown()

 注意:因邀月本机无Cassandra,因此未运行本实例,若有报错,请告知。谢谢!

 

8.10小结

   咱们能够把年度太阳黑子周期数据存储在不一样的数据库中,包括关系型数据库和NoSQL数据库。

  这里所谓的关系,不只限于数据表之间的关系,首先,它与一个数据表内部各列之间的关系有关;其次,它还涉及数据表之间的关系。

  实际上,咱们能够经过Python的标准模块sqlite3来跟SQLite数据库打交道。咱们能够经过pandas与SQLite数据库或SQLAlchemy数据库来创建链接。

  SQLAlchemy以其基于设计模式的ORM而闻名天下,经过这个库,能够把Python的类映射为数据库的数据表。实际上,ORM模式是一种通用的架构模式,所以一样适用于其余各类面向对象程序设计语言。SQLAlchemy将使用数据库的各类技术细节剥离出去,有了它,咱们甚至连SQL都不用写了。

  MongoDB是一个面向文档的数据仓库,能够存放巨量的数据。

  进入in-memory模式后,Redis不只运行速度极快,并且写操做也几乎与读操做同样快。Redis是一个键-值型数据仓库,功能上与Python的字典相仿。

  Apache Cassandra不只具备键-值数据库的特性,同时还具有传统的关系型数据库特性。这是一种面向列的数据库,它的各个列都以列族的形式组织在一块儿,这里的列族至关于关系型数据库中的数据表。在Apache Cassandra数据库中,数据行已经摆脱了特定列组合的束缚。

  第9章将介绍纯文本数据的分析技术,由于纯文本数据在各个组织和互联网上随处可见。通常来讲,纯文本数据的非结构化程度都很高,与处理已经清洗并制表的数据相比,分析纯文本数据须要使用一些大相径庭的方法。为了分析这类数据,咱们须要借助另外一个开源Python程序包,即NLTK。NLTK发展得已经很是完备,并且自身备有相应的数据集。

 

第8章完。

python数据分析我的学习读书笔记-目录索引

 

随书源码官方下载:
https://www.ptpress.com.cn/shopping/buy?bookId=bae24ecb-a1a1-41c7-be7c-d913b163c111

须要登陆后免费下载。

相关文章
相关标签/搜索