收录平时发现的,对解决特定问题的最好算法,包括官方库和第三方库。
全部在Python3下测试通过。
1. TOPN问题
即从列表中取出最大的N个元素。
import heapq
print(heapq.nlargest(10, alist))
2. TOPK问题
即从列表中取出值最大的N个元素的
import gensim
gensim.matutils.argsort(alist, 10, True)
3. 数据模型迭代器
做数据分析时,常需要对全表数据读取。一次读取到内存显然是不现实的,利用Python的Iterator机制,逐行读取数据,是一种比较方便的做法。
Mongo
Mongo本身支持游标(cursor),可直接使用。
import pymongo
conn = MongoClient('127.0.0.1', 27017)
db = conn.db1
cursor = db1.collection1.find()
for doc in cursor:
print(doc)
MySQL
MySQL本身不支持游标,也没有找到哪个库实现了这个功能。
可以封装一个迭代器包装类,通过反复定位查询来模拟迭代。
这里以ORM库peewee为例。
import peewee
# 建立数据库连接
conn = ...
# 建立数据模型
class TableTest():
class Meta:
table_name = 'test_tbl'
database = conn
id = IntegerField()
# mysql数据模型迭代器包装类
class ModelIterator(object):
start_id = 0
def __init__(self, model, step=50):
self.model = model
self.step = step
def __iter__(self):
rows = self.__getRows()
i = 0
while True:
if i >= self.step:
rows = self.__getRows()
if len(rows) < self.step:
break
i = -1
else:
yield rows[i]
i += 1
def __getRows(self):
rows = self.model\
.select()\
.where(self.model.id > self.start_id)\
.limit(self.step)\
.order_by(self.model.id)
self.start_id = rows[len(rows) - 1].id
return rows
# 通过迭代器迭代数据
for row in ModelIterator(TableTest):
print(row.id)
4. 巨型稀疏矩阵计算
在文本分析等工程过程中,常常会用矩阵表示数据关系,且矩阵中含大量0。
可以采用scipy库的稀疏形式表示矩阵,然后进行运算。稀疏表示可以节约大量内存,避免矩阵过大引起的爆内存问题。
最近项目中,需要将gensim的稀疏矩阵做点乘运算,如下:
# 4x5
m1 = [
[(0,6), (1,5), (3,5)],
[(0,6), (1,5), (3,0)],
[(0,6), (1,-5), (3,5)],
[(0,2), (1,6), (3,2)],
]
# 5x3
m2 = [
[(0,0.6), (1,0.7)],
[(0,0.4), (1,0.7)],
[(0,0.3), (2,0.25)],
[(0,0.2), (1,0.01)],
[(0,1.0), (1,0.35), (2,0.25)],
]
csc_m1 = gensim.matutils.corpus2csc(m1, num_terms=5)
csc_m2 = gensim.matutils.corpus2csc(m2, num_terms=3)
# 注意csc表示是转置的,需要再转回来
csc_uf = csc_ui.T.dot(csc_if.T)
5. 装饰器写法
import functools
# 定义装饰器
def decorator(f):
@functools.wraps(f)
def wrapper(*args, **kargs):
# do something
result = f(*args, **kargs)
# do something
return result
return wrapper
# 使用
@decorator
def foo():
pass
如果装饰器需要接收参数:
def decorator(params):
def decorator_(f):
@functools.wraps(f)
def wrapper(*args, **kargs):
# do something
result = f(*args, **kargs)
# do something
return result
return wrapper
return decorator_
# 使用
@decorator(params=...)
def foo():
pass