cv2 distanceTransform函数的用法 python

李魔佛 发表了文章 • 0 个评论 • 4910 次浏览 • 2019-07-08 15:35 • 来自相关话题

distanceTransform
Calculates the distance to the closest zero pixel for each pixel of the source image.


Python: cv2.distanceTransform(src, distanceType, maskSize[, dst]) → dst

Python: cv.DistTransform(src, dst, distance_type=CV_DIST_L2, mask_size=3, mask=None, labels=None) → None
Parameters:
src – 8-bit, single-channel (binary) source image.
dst – Output image with calculated distances. It is a 32-bit floating-point, single-channel image of the same size as src .
distanceType – Type of distance. It can be CV_DIST_L1, CV_DIST_L2 , or CV_DIST_C .
maskSize – Size of the distance transform mask. It can be 3, 5, or CV_DIST_MASK_PRECISE (the latter option is only supported by the first function). In case of the CV_DIST_L1 or CV_DIST_C distance type, the parameter is forced to 3 because a 3\times 3 mask gives the same result as 5\times 5 or any larger aperture.
labels – Optional output 2D array of labels (the discrete Voronoi diagram). It has the type CV_32SC1 and the same size as src . See the details below.
labelType – Type of the label array to build. If labelType==DIST_LABEL_CCOMP then each connected component of zeros in src (as well as all the non-zero pixels closest to the connected component) will be assigned the same label. If labelType==DIST_LABEL_PIXEL then each zero pixel (and all the non-zero pixels closest to it) gets its own label.
The functions distanceTransform calculate the approximate or precise distance from every binary image pixel to the nearest zero pixel. For zero image pixels, the distance will obviously be zero.


When maskSize == CV_DIST_MASK_PRECISE and distanceType == CV_DIST_L2 , the function runs the algorithm described in [Felzenszwalb04]. This algorithm is parallelized with the TBB library.

In other cases, the algorithm [Borgefors86] is used. This means that for a pixel the function finds the shortest path to the nearest zero pixel consisting of basic shifts: horizontal, vertical, diagonal, or knight’s move (the latest is available for a 5\times 5 mask). The overall distance is calculated as a sum of these basic distances. Since the distance function should be symmetric, all of the horizontal and vertical shifts must have the same cost (denoted as a ), all the diagonal shifts must have the same cost (denoted as b ), and all knight’s moves must have the same cost (denoted as c ). For the CV_DIST_C and CV_DIST_L1 types, the distance is calculated precisely, whereas for CV_DIST_L2 (Euclidean distance) the distance can be calculated only with a relative error (a 5\times 5 mask gives more accurate results). For a,``b`` , and c , OpenCV uses the values suggested in the original paper:

CV_DIST_C (3\times 3) a = 1, b = 1
CV_DIST_L1 (3\times 3) a = 1, b = 2
CV_DIST_L2 (3\times 3) a=0.955, b=1.3693
CV_DIST_L2 (5\times 5) a=1, b=1.4, c=2.1969
Typically, for a fast, coarse distance estimation CV_DIST_L2, a 3\times 3 mask is used. For a more accurate distance estimation CV_DIST_L2 , a 5\times 5 mask or the precise algorithm is used. Note that both the precise and the approximate algorithms are linear on the number of pixels.

The second variant of the function does not only compute the minimum distance for each pixel (x, y) but also identifies the nearest connected component consisting of zero pixels (labelType==DIST_LABEL_CCOMP) or the nearest zero pixel (labelType==DIST_LABEL_PIXEL). Index of the component/pixel is stored in \texttt{labels}(x, y) . When labelType==DIST_LABEL_CCOMP, the function automatically finds connected components of zero pixels in the input image and marks them with distinct labels. When labelType==DIST_LABEL_CCOMP, the function scans through the input image and marks all the zero pixels with distinct labels.

In this mode, the complexity is still linear. That is, the function provides a very fast way to compute the Voronoi diagram for a binary image. Currently, the second variant can use only the approximate distance transform algorithm, i.e. maskSize=CV_DIST_MASK_PRECISE is not supported yet.

Note
An example on using the distance transform can be found at opencv_source_code/samples/cpp/distrans.cpp
(Python) An example on using the distance transform can be found at opencv_source/samples/python2/distrans.py 

  查看全部
distanceTransform
Calculates the distance to the closest zero pixel for each pixel of the source image.


Python: cv2.distanceTransform(src, distanceType, maskSize[, dst]) → dst

Python: cv.DistTransform(src, dst, distance_type=CV_DIST_L2, mask_size=3, mask=None, labels=None) → None

Parameters:
src – 8-bit, single-channel (binary) source image.
dst – Output image with calculated distances. It is a 32-bit floating-point, single-channel image of the same size as src .

distanceType – Type of distance. It can be CV_DIST_L1, CV_DIST_L2 , or CV_DIST_C .
maskSize – Size of the distance transform mask. It can be 3, 5, or CV_DIST_MASK_PRECISE (the latter option is only supported by the first function). In case of the CV_DIST_L1 or CV_DIST_C distance type, the parameter is forced to 3 because a 3\times 3 mask gives the same result as 5\times 5 or any larger aperture.

labels – Optional output 2D array of labels (the discrete Voronoi diagram). It has the type CV_32SC1 and the same size as src . See the details below.

labelType – Type of the label array to build. If labelType==DIST_LABEL_CCOMP then each connected component of zeros in src (as well as all the non-zero pixels closest to the connected component) will be assigned the same label. If labelType==DIST_LABEL_PIXEL then each zero pixel (and all the non-zero pixels closest to it) gets its own label.
The functions distanceTransform calculate the approximate or precise distance from every binary image pixel to the nearest zero pixel. For zero image pixels, the distance will obviously be zero.


When maskSize == CV_DIST_MASK_PRECISE and distanceType == CV_DIST_L2 , the function runs the algorithm described in [Felzenszwalb04]. This algorithm is parallelized with the TBB library.

In other cases, the algorithm [Borgefors86] is used. This means that for a pixel the function finds the shortest path to the nearest zero pixel consisting of basic shifts: horizontal, vertical, diagonal, or knight’s move (the latest is available for a 5\times 5 mask). The overall distance is calculated as a sum of these basic distances. Since the distance function should be symmetric, all of the horizontal and vertical shifts must have the same cost (denoted as a ), all the diagonal shifts must have the same cost (denoted as b ), and all knight’s moves must have the same cost (denoted as c ). For the CV_DIST_C and CV_DIST_L1 types, the distance is calculated precisely, whereas for CV_DIST_L2 (Euclidean distance) the distance can be calculated only with a relative error (a 5\times 5 mask gives more accurate results). For a,``b`` , and c , OpenCV uses the values suggested in the original paper:

CV_DIST_C (3\times 3) a = 1, b = 1
CV_DIST_L1 (3\times 3) a = 1, b = 2
CV_DIST_L2 (3\times 3) a=0.955, b=1.3693
CV_DIST_L2 (5\times 5) a=1, b=1.4, c=2.1969
Typically, for a fast, coarse distance estimation CV_DIST_L2, a 3\times 3 mask is used. For a more accurate distance estimation CV_DIST_L2 , a 5\times 5 mask or the precise algorithm is used. Note that both the precise and the approximate algorithms are linear on the number of pixels.

The second variant of the function does not only compute the minimum distance for each pixel (x, y) but also identifies the nearest connected component consisting of zero pixels (labelType==DIST_LABEL_CCOMP) or the nearest zero pixel (labelType==DIST_LABEL_PIXEL). Index of the component/pixel is stored in \texttt{labels}(x, y) . When labelType==DIST_LABEL_CCOMP, the function automatically finds connected components of zero pixels in the input image and marks them with distinct labels. When labelType==DIST_LABEL_CCOMP, the function scans through the input image and marks all the zero pixels with distinct labels.

In this mode, the complexity is still linear. That is, the function provides a very fast way to compute the Voronoi diagram for a binary image. Currently, the second variant can use only the approximate distance transform algorithm, i.e. maskSize=CV_DIST_MASK_PRECISE is not supported yet.

Note
An example on using the distance transform can be found at opencv_source_code/samples/cpp/distrans.cpp
(Python) An example on using the distance transform can be found at opencv_source/samples/python2/distrans.py
 

 

Win10下PhantomJS无法运行 【版本兼容问题】

李魔佛 发表了文章 • 0 个评论 • 2146 次浏览 • 2019-07-04 09:07 • 来自相关话题

以前在win7上运行的好好的。
在win10下就报错:
selenium.common.exceptions.WebDriverException: Message: Service C:\Tool\phantomjs-2.5.0-beta2-windows\phantomjs-2.5.0-beta2-windows\bin\phantomjs.exe unexpectedly exited. Status code was: 4294967295
 
后来替换了一个旧的版本,发现问题就这么解决了。
旧版本:phantomjs-2.1.1-windows
 
原创文章
转载请注明出处 
http://30daydo.com/article/505
  查看全部
以前在win7上运行的好好的。
在win10下就报错:
selenium.common.exceptions.WebDriverException: Message: Service C:\Tool\phantomjs-2.5.0-beta2-windows\phantomjs-2.5.0-beta2-windows\bin\phantomjs.exe unexpectedly exited. Status code was: 4294967295
 
后来替换了一个旧的版本,发现问题就这么解决了。
旧版本:phantomjs-2.1.1-windows
 
原创文章
转载请注明出处 
http://30daydo.com/article/505
 

python3与python2迭代器的写法的区别

李魔佛 发表了文章 • 0 个评论 • 810 次浏览 • 2019-06-26 11:22 • 来自相关话题

大部分相同,只是python2里面需要实现在类中实现next()方法,而python3里面需要实现__next__()方法。
 
附一个例子:
def iter_demo():

class DefineIter(object):

def __init__(self,length):
self.length = length
self.data = range(self.length)
self.index=0

def __iter__(self):
return self


def __next__(self):

if self.index >=self.length:
# return None
raise StopIteration

d = self.data[self.index]*50
self.index =self.index + 1

return d

a = DefineIter(10)
print(type(a))
for i in a:
print(i) 查看全部
大部分相同,只是python2里面需要实现在类中实现next()方法,而python3里面需要实现__next__()方法。
 
附一个例子:
def iter_demo():

class DefineIter(object):

def __init__(self,length):
self.length = length
self.data = range(self.length)
self.index=0

def __iter__(self):
return self


def __next__(self):

if self.index >=self.length:
# return None
raise StopIteration

d = self.data[self.index]*50
self.index =self.index + 1

return d

a = DefineIter(10)
print(type(a))
for i in a:
print(i)

PyCharm 快捷键快速插入当前时间

李魔佛 发表了文章 • 0 个评论 • 1111 次浏览 • 2019-06-26 09:18 • 来自相关话题

个人觉得这是一个非常常用的功能,不过需要自定义实现。
 
方式
通过 Live Template 快速添加时间

步骤
1、添加一个 Template Group 命名为 Common
2、添加一个 Live Template 设置如下
Abbreviation: time
Description : current time
Template Text: $time$

Edit Variables -> Expresssion : date("yyyy-MM-dd HH:mm:ss")



3、让设置生效
Define->Everywhere

4、使用
输入 time 后 按下tab键 就能转换为当前时间了
  查看全部
个人觉得这是一个非常常用的功能,不过需要自定义实现。
 
方式
通过 Live Template 快速添加时间

步骤
1、添加一个 Template Group 命名为 Common
2、添加一个 Live Template 设置如下
Abbreviation: time
Description : current time
Template Text: $time$

Edit Variables -> Expresssion : date("yyyy-MM-dd HH:mm:ss")



3、让设置生效
Define->Everywhere

4、使用
输入 time 后 按下tab键 就能转换为当前时间了

 

conda无法在win10下用命令行切换虚拟环境

李魔佛 发表了文章 • 0 个评论 • 1760 次浏览 • 2019-06-11 10:04 • 来自相关话题

虚拟环境已经安装好了
然后在PowerShell下运行activate py2,没有任何反应。(powershell是win7后面系统的增强命令行)
后来使用系统原始的cmd命令行,在运行里面敲入cmd,然后重新执行activate py2,问题得到解决了。
原因是兼容问题。 查看全部
虚拟环境已经安装好了
然后在PowerShell下运行activate py2,没有任何反应。(powershell是win7后面系统的增强命令行)
后来使用系统原始的cmd命令行,在运行里面敲入cmd,然后重新执行activate py2,问题得到解决了。
原因是兼容问题。

jupyter notebook格式的文件损坏如何修复

李魔佛 发表了文章 • 0 个评论 • 1293 次浏览 • 2019-06-08 13:44 • 来自相关话题

有时候用git同步时,造成了冲突后合并,jupyter notebook的文件被插入了诸如>>>>>HEAD,ORIGIN等字符,这时候再打开jupyter notebook文件(.ipynb后缀),会无法打开。修复过程:
 
使用下面的代码:
# 拯救损坏的jupyter 文件
import re
import codecs

pattern = re.compile('"source": \[(.*?)\]\s+\},',re.S)
filename = 'tushare_usage.ipynb'
with codecs.open(filename,encoding='utf8') as f:
content = f.read()

source = pattern.findall(content)
for s in source:
t=s.replace('\\n','')
t=re.sub('"','',t)
t=re.sub('(,$)','',t)
print(t)只要把你要修复的文件替换一下就可以了。 查看全部
有时候用git同步时,造成了冲突后合并,jupyter notebook的文件被插入了诸如>>>>>HEAD,ORIGIN等字符,这时候再打开jupyter notebook文件(.ipynb后缀),会无法打开。修复过程:
 
使用下面的代码:
# 拯救损坏的jupyter 文件
import re
import codecs

pattern = re.compile('"source": \[(.*?)\]\s+\},',re.S)
filename = 'tushare_usage.ipynb'
with codecs.open(filename,encoding='utf8') as f:
content = f.read()

source = pattern.findall(content)
for s in source:
t=s.replace('\\n','')
t=re.sub('"','',t)
t=re.sub('(,$)','',t)
print(t)
只要把你要修复的文件替换一下就可以了。

python的mixin类

李魔佛 发表了文章 • 0 个评论 • 868 次浏览 • 2019-05-16 16:30 • 来自相关话题

A mixin is a limited form of multiple inheritance.
 
maxin类似多重继承的一种限制形式:
 关于Python的Mixin模式

像C或C++这类语言都支持多重继承,一个子类可以有多个父类,这样的设计常被人诟病。因为继承应该是个”is-a”关系。比如轿车类继承交通工具类,因为轿车是一个(“is-a”)交通工具。一个物品不可能是多种不同的东西,因此就不应该存在多重继承。不过有没有这种情况,一个类的确是需要继承多个类呢?

答案是有,我们还是拿交通工具来举例子,民航飞机是一种交通工具,对于土豪们来说直升机也是一种交通工具。对于这两种交通工具,它们都有一个功能是飞行,但是轿车没有。所以,我们不可能将飞行功能写在交通工具这个父类中。但是如果民航飞机和直升机都各自写自己的飞行方法,又违背了代码尽可能重用的原则(如果以后飞行工具越来越多,那会出现许多重复代码)。怎么办,那就只好让这两种飞机同时继承交通工具以及飞行器两个父类,这样就出现了多重继承。这时又违背了继承必须是”is-a”关系。这个难题该怎么破?

不同的语言给出了不同的方法,让我们先来看下Java。Java提供了接口interface功能,来实现多重继承:public abstract class Vehicle {
}

public interface Flyable {
public void fly();
}

public class FlyableImpl implements Flyable {
public void fly() {
System.out.println("I am flying");
}
}

public class Airplane extends Vehicle implements Flyable {
private flyable;

public Airplane() {
flyable = new FlyableImpl();
}

public void fly() {
flyable.fly();
}
}

现在我们的飞机同时具有了交通工具及飞行器两种属性,而且我们不需要重写飞行器中的飞行方法,同时我们没有破坏单一继承的原则。飞机就是一种交通工具,可飞行的能力是是飞机的属性,通过继承接口来获取。

回到主题,Python语言可没有接口功能,但是它可以多重继承。那Python是不是就该用多重继承来实现呢?是,也不是。说是,因为从语法上看,的确是通过多重继承实现的。说不是,因为它的继承依然遵守”is-a”关系,从含义上看依然遵循单继承的原则。这个怎么理解呢?我们还是看例子吧。
class Vehicle(object):
pass

class PlaneMixin(object):
def fly(self):
print 'I am flying'

class Airplane(Vehicle, PlaneMixin):
pass

可以看到,上面的Airplane类实现了多继承,不过它继承的第二个类我们起名为PlaneMixin,而不是Plane,这个并不影响功能,但是会告诉后来读代码的人,这个类是一个Mixin类。所以从含义上理解,Airplane只是一个Vehicle,不是一个Plane。这个Mixin,表示混入(mix-in),它告诉别人,这个类是作为功能添加到子类中,而不是作为父类,它的作用同Java中的接口。

使用Mixin类实现多重继承要非常小心
首先它必须表示某一种功能,而不是某个物品,如同Java中的Runnable,Callable等
 
其次它必须责任单一,如果有多个功能,那就写多个Mixin类然后,它不依赖于子类的实现最后,子类即便没有继承这个Mixin类,也照样可以工作,就是缺少了某个功能。(比如飞机照样可以载客,就是不能飞了^_^) 查看全部
A mixin is a limited form of multiple inheritance.
 
maxin类似多重继承的一种限制形式:
 关于Python的Mixin模式

像C或C++这类语言都支持多重继承,一个子类可以有多个父类,这样的设计常被人诟病。因为继承应该是个”is-a”关系。比如轿车类继承交通工具类,因为轿车是一个(“is-a”)交通工具。一个物品不可能是多种不同的东西,因此就不应该存在多重继承。不过有没有这种情况,一个类的确是需要继承多个类呢?

答案是有,我们还是拿交通工具来举例子,民航飞机是一种交通工具,对于土豪们来说直升机也是一种交通工具。对于这两种交通工具,它们都有一个功能是飞行,但是轿车没有。所以,我们不可能将飞行功能写在交通工具这个父类中。但是如果民航飞机和直升机都各自写自己的飞行方法,又违背了代码尽可能重用的原则(如果以后飞行工具越来越多,那会出现许多重复代码)。怎么办,那就只好让这两种飞机同时继承交通工具以及飞行器两个父类,这样就出现了多重继承。这时又违背了继承必须是”is-a”关系。这个难题该怎么破?

不同的语言给出了不同的方法,让我们先来看下Java。Java提供了接口interface功能,来实现多重继承:
public abstract class Vehicle {
}

public interface Flyable {
public void fly();
}

public class FlyableImpl implements Flyable {
public void fly() {
System.out.println("I am flying");
}
}

public class Airplane extends Vehicle implements Flyable {
private flyable;

public Airplane() {
flyable = new FlyableImpl();
}

public void fly() {
flyable.fly();
}
}


现在我们的飞机同时具有了交通工具及飞行器两种属性,而且我们不需要重写飞行器中的飞行方法,同时我们没有破坏单一继承的原则。飞机就是一种交通工具,可飞行的能力是是飞机的属性,通过继承接口来获取。

回到主题,Python语言可没有接口功能,但是它可以多重继承。那Python是不是就该用多重继承来实现呢?是,也不是。说是,因为从语法上看,的确是通过多重继承实现的。说不是,因为它的继承依然遵守”is-a”关系,从含义上看依然遵循单继承的原则。这个怎么理解呢?我们还是看例子吧。
class Vehicle(object):
pass

class PlaneMixin(object):
def fly(self):
print 'I am flying'

class Airplane(Vehicle, PlaneMixin):
pass


可以看到,上面的Airplane类实现了多继承,不过它继承的第二个类我们起名为PlaneMixin,而不是Plane,这个并不影响功能,但是会告诉后来读代码的人,这个类是一个Mixin类。所以从含义上理解,Airplane只是一个Vehicle,不是一个Plane。这个Mixin,表示混入(mix-in),它告诉别人,这个类是作为功能添加到子类中,而不是作为父类,它的作用同Java中的接口。

使用Mixin类实现多重继承要非常小心
  • 首先它必须表示某一种功能,而不是某个物品,如同Java中的Runnable,Callable等

 
  • 其次它必须责任单一,如果有多个功能,那就写多个Mixin类
  • 然后,它不依赖于子类的实现
  • 最后,子类即便没有继承这个Mixin类,也照样可以工作,就是缺少了某个功能。(比如飞机照样可以载客,就是不能飞了^_^)

python不支持多重继承中的重复继承

李魔佛 发表了文章 • 0 个评论 • 696 次浏览 • 2019-04-18 16:36 • 来自相关话题

代码如下:
class First(object):
def __init__(self):
print("first")

class Second(First):
def __init__(self):
print("second")

class Third(First,Second):
def __init__(self):
print("third")
运行代码会直接报错:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-c90f7b77d3e0> in <module>()
7 print("second")
8
----> 9 class Third(First,Second):
10 def __init__(self):
11 print("third")

TypeError: Cannot create a consistent method resolution order (MRO) for bases First, Second
  查看全部
代码如下:
class First(object):
def __init__(self):
print("first")

class Second(First):
def __init__(self):
print("second")

class Third(First,Second):
def __init__(self):
print("third")

运行代码会直接报错:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-c90f7b77d3e0> in <module>()
7 print("second")
8
----> 9 class Third(First,Second):
10 def __init__(self):
11 print("third")

TypeError: Cannot create a consistent method resolution order (MRO) for bases First, Second

 

gevent异步 入门教程(入坑)

李魔佛 发表了文章 • 0 个评论 • 997 次浏览 • 2019-04-18 11:37 • 来自相关话题

code1
import time
import gevent
import requests
def foo():
print('Running in foo')

r=requests.get('http://30daydo.com')
print(r.status_code)
print('Explicit context switch to foo again')

def bar():
print('Explicit context to bar')

r=requests.get('http://www.qq.com') #
print(r.status_code)
print('Implicit context switch back to bar')

start=time.time()
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
print('time used {}'.format(time.time()-start))
上面的异步代码不起作用,因为requests阻塞了,所以用的时间和顺序执行的时间一样.
 
或者用以下代码替代:
import time
import gevent
import requests
def foo():
print('Running in foo')
time.sleep(2) # 这样子不起作用
print('Explicit context switch to foo again')

def bar():
print('Explicit context to bar')
time.sleep(2)
print('Implicit context switch back to bar')

start=time.time()
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
print('time used {}'.format(time.time()-start))
把访问网络部分使用sleep替代,那么最后的运行时间是2+2 =4秒,并不是2秒,那么要怎样才是2秒呢,需要改成以下的代码:
 
import time
import gevent
import requests
def foo():
print('Running in foo')

gevent.sleep(2) # 通过它各自yield向对方

print('Explicit context switch to foo again')

def bar():
print('Explicit context to bar')

gevent.sleep(2)

print('Implicit context switch back to bar')

start=time.time()
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
print('time used {}'.format(time.time()-start))
使用gevent.sleep()
这个函数才可以达到目的. 查看全部
code1
import time
import gevent
import requests
def foo():
print('Running in foo')

r=requests.get('http://30daydo.com')
print(r.status_code)
print('Explicit context switch to foo again')

def bar():
print('Explicit context to bar')

r=requests.get('http://www.qq.com') #
print(r.status_code)
print('Implicit context switch back to bar')

start=time.time()
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
print('time used {}'.format(time.time()-start))

上面的异步代码不起作用,因为requests阻塞了,所以用的时间和顺序执行的时间一样.
 
或者用以下代码替代:
import time
import gevent
import requests
def foo():
print('Running in foo')
time.sleep(2) # 这样子不起作用
print('Explicit context switch to foo again')

def bar():
print('Explicit context to bar')
time.sleep(2)
print('Implicit context switch back to bar')

start=time.time()
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
print('time used {}'.format(time.time()-start))

把访问网络部分使用sleep替代,那么最后的运行时间是2+2 =4秒,并不是2秒,那么要怎样才是2秒呢,需要改成以下的代码:
 
import time
import gevent
import requests
def foo():
print('Running in foo')

gevent.sleep(2) # 通过它各自yield向对方

print('Explicit context switch to foo again')

def bar():
print('Explicit context to bar')

gevent.sleep(2)

print('Implicit context switch back to bar')

start=time.time()
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
print('time used {}'.format(time.time()-start))

使用gevent.sleep()
这个函数才可以达到目的.

python的pip安装mysqldb

李魔佛 发表了文章 • 0 个评论 • 872 次浏览 • 2019-04-16 23:51 • 来自相关话题

换一个新环境,或者在另一台服务器上运行自己的程序,最烦就是pip安装各种依赖,尤其其他机器上的python不一致(你用的是python3,服务器用的是python2),或者两个系统都不一致。 这个时候pip安装第三方库就很折腾。
 
比如mysqldb这个库,windows用python2不知道怎样才能装上。 反正这个我几年装过,现在已经忘记怎么安装了。
今天又要装一遍,为了减轻痛苦,安装anaconda,然后使用conda install mysqldb,conda会帮你把依赖都解决掉。 不然你要装一堆的VC8,VC14, 等等。
 
然后等待一下,就安装好了。 查看全部
换一个新环境,或者在另一台服务器上运行自己的程序,最烦就是pip安装各种依赖,尤其其他机器上的python不一致(你用的是python3,服务器用的是python2),或者两个系统都不一致。 这个时候pip安装第三方库就很折腾。
 
比如mysqldb这个库,windows用python2不知道怎样才能装上。 反正这个我几年装过,现在已经忘记怎么安装了。
今天又要装一遍,为了减轻痛苦,安装anaconda,然后使用conda install mysqldb,conda会帮你把依赖都解决掉。 不然你要装一堆的VC8,VC14, 等等。
 
然后等待一下,就安装好了。

最流行的版本控制软件:git 个人笔记

李魔佛 发表了文章 • 0 个评论 • 750 次浏览 • 2019-04-16 23:37 • 来自相关话题

最流行的版本控制软件:git
========================

git已经是当前最流行的版本控制软件之一了。全世界的程序员都在使用它。它出自linus大神之手,现在被用于内
核的版本控制。在最流行的代码托管软件github,你几乎可以找到所有开源项目的代码。

版块控制软件:我需要吗?
-----------------------

的确对于许多人——尤其是非程序员,他们可能不会想到已经出现了专门的版本控制的软件。但其实多人对版本控
制其实都有类似的需求,举个例子,Tom是社团的秘书处成员,他们经常需要做的事情就是写活动文档,然后不停地
改改到大家都觉得可以了。

不幸运的话,Tom可能有个文件夹叫“openSUSE活动策划",里面有这样的一堆文件”openSUSE活动策划", "活动策
划1", "活动策划2", "活动策划3", "活动策划4" ... "活动策划20" (可怜的Tom,一份文档改了不少于20次)

这种作法很有效,因为我们可能发现第5个版本的策划有问题,我们准备在第3个版本上面重新来过。但是也看到,
这个作法有些很丑陋的地方:一份文件,我们留了20个备份,而且还要注意文件名。

如果可以这样就好了:文件夹上只有一个“openSUSE活动策划",但当我需要第5个版本的时候,我来一个”给我还
原到第5个版本吧!“,然后这时候我们打开这个文件,它就是第5个版本的了。类似的,我们可以取出任意的版本


这就是版本控制。这种事情在程序里面发生的太多了,于是出现了各种版本控制软件。事实上,有些项目已经发展
到第1000+甚至更高的版本数了……

单线的工作流
------------

我们可以把我们的一个项目想象为一个仓库,然后我们可以把我们的东西塞进仓库里面,也可以把想要的东西拿出
来。而git则是仓库的管理员。下面是一个例子,希望有一个直观的印象,不求完全的理解和掌握。

```bash
mkdir myproject // 假设myproject是工作目录
cd myproject
git init // git <- (init) ,告诉仓库管理员,在当前目录初始化
echo 'Eat the banana' > file // 编辑了一个文件
git add file // 加入仓库
git commit -m 'add first file' // 提交更改
echo 'Eat the apply' > file // 修改了这个文件
git add file // 加入仓库
git commit -m 'update first file' // 再提交更改
```

这时候我们就有两个commit了,我们来看看工作日志:

```bash
git log

# 以下是输出
# commit ac1371173b4e630ddaebda3f9f5d948b36146c07
# Author: Norman Mo <LTaoist@@@>
# Date: Thu Jun 27 21:59:10 2013 +0800
#
# update first file
#
# commit 3c43cc913454f92bb4b80c56ba45e4ffaf556fc0
# Author: Norman Mo <LTaoist6@@@@>
# Date: Thu Jun 27 21:58:48 2013 +0800
#
# add first file
```

看到了,我们提交了两次。我们来看看现在file里面是什么:

```bash
cat file # 显然输出是 'Eat the apply'
# 现在,我们来拿回第一个版本的file文件
git checkout 3c43cc913454f92bb4b80c56ba45e4ffaf556fc0 -- file
cat file # 这时候就是eat banana了
```

这种工作的方式是单人使用最常见的方式,写一点代码,提交一下到仓库里面。写一点,提交到仓库里面。然后出
问题的时候就回退过去。git非常强大,基本上你想到的他都可以做到,提交到仓库的数据基本不会丢失,像时间机
器一样控制着代码。

多人协作
--------

git非常强大,上面只是一个功能。考虑Tom的秘书处有两个人,他们在同时写。其中Tom写前6章,他的同伴写第7~
12章。

这时候可以考虑用这种工作的方式:设立一个公共的仓库。Tom维护自己的版本,他的同伴维护自己的版本。然后大
家定期把代码合并到公共仓库上面,然后定期把新的版本取回来合并再提交到公共仓库。

如果他们用纯文本,得益于一些文本分析的方法,几乎不需要校对就可以做到。

```
git commit -m 'finish ch5' // 假设此时Tom写完了第5章
git push // Tom将代码推送到远程仓库
```

```
git commit -m 'finish ch11' // 假设此时Tom的同伴完成了第11章
git pull // pull会将最新版本拉下来,合并,然后推送到远程仓库
```

实际上工作中,为了不混淆,会新开一个分支来开发新的特性,然后对分支进行合并。

代码自动发布
-----------

另一个很强大的功能是可以实现代码的自动发布。事实上,很多云就有使用这个。具体来说,利用git的hooks,当
服务器收到一个push,服务器可以自动运行一些脚本。也可以在客户端使用hooks,当客户端准备push的时候,客户
端先运行一些脚本。

例如,我们希望在每次服务器收到push以后,杀死全部的 `p` 进程,然后重开 `p` 进程。我们可以修改 `hooks/
post-receive` :

```
echo "Killing all p process..."
killall -9 p
echo "Restart p process..."
p
```

更多更多更多……
---------------

这份教程就到这里了,更多的自己马上动手去试试吧!

在openSUSE的安装方法:

```
sudo zypper in git
```

默认应该就装了。

一般linux命令查看帮助都是 `--help` 选项:

```
git --help
```

此外,对一个子命令也是有help看的:

```
git init --help
```

这里有一个交互教程,在浏览器上面跑的模拟git的运行的,有兴趣的试试:

<http://try.github.io/>

github的help文档写得很不错,推荐一下:

<https://help.github.com/>

书籍有个远近闻名的《Pro Git》,而且有中文版的,虽然我认为这本书太厚了。。。但似乎就这么一本书……

<http://git-scm.com/book/zh>

国内有个gitcafe,也是做git托管的,他们也有整理一份help:

<https://gitcafe.com/GitCafe/Help>

记得,上面只是一个演示,多试试push,多尝试。有一天你会喜欢用这个有效的工具的。

很有用!!! 查看全部

最流行的版本控制软件:git
========================

git已经是当前最流行的版本控制软件之一了。全世界的程序员都在使用它。它出自linus大神之手,现在被用于内
核的版本控制。在最流行的代码托管软件github,你几乎可以找到所有开源项目的代码。

版块控制软件:我需要吗?
-----------------------

的确对于许多人——尤其是非程序员,他们可能不会想到已经出现了专门的版本控制的软件。但其实多人对版本控
制其实都有类似的需求,举个例子,Tom是社团的秘书处成员,他们经常需要做的事情就是写活动文档,然后不停地
改改到大家都觉得可以了。

不幸运的话,Tom可能有个文件夹叫“openSUSE活动策划",里面有这样的一堆文件”openSUSE活动策划", "活动策
划1", "活动策划2", "活动策划3", "活动策划4" ... "活动策划20" (可怜的Tom,一份文档改了不少于20次)

这种作法很有效,因为我们可能发现第5个版本的策划有问题,我们准备在第3个版本上面重新来过。但是也看到,
这个作法有些很丑陋的地方:一份文件,我们留了20个备份,而且还要注意文件名。

如果可以这样就好了:文件夹上只有一个“openSUSE活动策划",但当我需要第5个版本的时候,我来一个”给我还
原到第5个版本吧!“,然后这时候我们打开这个文件,它就是第5个版本的了。类似的,我们可以取出任意的版本


这就是版本控制。这种事情在程序里面发生的太多了,于是出现了各种版本控制软件。事实上,有些项目已经发展
到第1000+甚至更高的版本数了……

单线的工作流
------------

我们可以把我们的一个项目想象为一个仓库,然后我们可以把我们的东西塞进仓库里面,也可以把想要的东西拿出
来。而git则是仓库的管理员。下面是一个例子,希望有一个直观的印象,不求完全的理解和掌握。

```bash
mkdir myproject // 假设myproject是工作目录
cd myproject
git init // git <- (init) ,告诉仓库管理员,在当前目录初始化
echo 'Eat the banana' > file // 编辑了一个文件
git add file // 加入仓库
git commit -m 'add first file' // 提交更改
echo 'Eat the apply' > file // 修改了这个文件
git add file // 加入仓库
git commit -m 'update first file' // 再提交更改
```

这时候我们就有两个commit了,我们来看看工作日志:

```bash
git log

# 以下是输出
# commit ac1371173b4e630ddaebda3f9f5d948b36146c07
# Author: Norman Mo <LTaoist@@@>
# Date: Thu Jun 27 21:59:10 2013 +0800
#
# update first file
#
# commit 3c43cc913454f92bb4b80c56ba45e4ffaf556fc0
# Author: Norman Mo <LTaoist6@@@@>
# Date: Thu Jun 27 21:58:48 2013 +0800
#
# add first file
```

看到了,我们提交了两次。我们来看看现在file里面是什么:

```bash
cat file # 显然输出是 'Eat the apply'
# 现在,我们来拿回第一个版本的file文件
git checkout 3c43cc913454f92bb4b80c56ba45e4ffaf556fc0 -- file
cat file # 这时候就是eat banana了
```

这种工作的方式是单人使用最常见的方式,写一点代码,提交一下到仓库里面。写一点,提交到仓库里面。然后出
问题的时候就回退过去。git非常强大,基本上你想到的他都可以做到,提交到仓库的数据基本不会丢失,像时间机
器一样控制着代码。

多人协作
--------

git非常强大,上面只是一个功能。考虑Tom的秘书处有两个人,他们在同时写。其中Tom写前6章,他的同伴写第7~
12章。

这时候可以考虑用这种工作的方式:设立一个公共的仓库。Tom维护自己的版本,他的同伴维护自己的版本。然后大
家定期把代码合并到公共仓库上面,然后定期把新的版本取回来合并再提交到公共仓库。

如果他们用纯文本,得益于一些文本分析的方法,几乎不需要校对就可以做到。

```
git commit -m 'finish ch5' // 假设此时Tom写完了第5章
git push // Tom将代码推送到远程仓库
```

```
git commit -m 'finish ch11' // 假设此时Tom的同伴完成了第11章
git pull // pull会将最新版本拉下来,合并,然后推送到远程仓库
```

实际上工作中,为了不混淆,会新开一个分支来开发新的特性,然后对分支进行合并。

代码自动发布
-----------

另一个很强大的功能是可以实现代码的自动发布。事实上,很多云就有使用这个。具体来说,利用git的hooks,当
服务器收到一个push,服务器可以自动运行一些脚本。也可以在客户端使用hooks,当客户端准备push的时候,客户
端先运行一些脚本。

例如,我们希望在每次服务器收到push以后,杀死全部的 `p` 进程,然后重开 `p` 进程。我们可以修改 `hooks/
post-receive` :

```
echo "Killing all p process..."
killall -9 p
echo "Restart p process..."
p
```

更多更多更多……
---------------

这份教程就到这里了,更多的自己马上动手去试试吧!

在openSUSE的安装方法:

```
sudo zypper in git
```

默认应该就装了。

一般linux命令查看帮助都是 `--help` 选项:

```
git --help
```

此外,对一个子命令也是有help看的:

```
git init --help
```

这里有一个交互教程,在浏览器上面跑的模拟git的运行的,有兴趣的试试:

<http://try.github.io/>

github的help文档写得很不错,推荐一下:

<https://help.github.com/>

书籍有个远近闻名的《Pro Git》,而且有中文版的,虽然我认为这本书太厚了。。。但似乎就这么一本书……

<http://git-scm.com/book/zh>

国内有个gitcafe,也是做git托管的,他们也有整理一份help:

<https://gitcafe.com/GitCafe/Help>

记得,上面只是一个演示,多试试push,多尝试。有一天你会喜欢用这个有效的工具的。

很有用!!!

python 爬虫使用urlretrieve下载时一直报错

李魔佛 回复了问题 • 2 人关注 • 1 个回复 • 2090 次浏览 • 2019-04-11 09:53 • 来自相关话题

numpy datetime转为date,pandas的日期类型转为python的daetime

李魔佛 发表了文章 • 0 个评论 • 3139 次浏览 • 2019-04-08 15:40 • 来自相关话题

dataframe的数据格式是这样子的:





 
info看一下里面的数据类型:<class 'pandas.core.frame.DataFrame'>
RangeIndex: 307 entries, 0 to 306
Data columns (total 7 columns):
日期 307 non-null datetime64[ns]
指数 307 non-null float64
成交额(亿元) 307 non-null float64
涨跌 307 non-null float64
涨跌额 307 non-null float64
转债数目 307 non-null float64
剩余规模 307 non-null float64
dtypes: datetime64[ns](1), float64(6)
memory usage: 16.9 KB
日期 307 non-null datetime64[ns]
 
然后转为list看看:
a=list(df['日期'].values)
如果使用上面的方法,返回的是这样的数据:[numpy.datetime64('2017-12-29T00:00:00.000000000'),
numpy.datetime64('2018-01-02T00:00:00.000000000'),
numpy.datetime64('2018-01-03T00:00:00.000000000'),
numpy.datetime64('2018-01-04T00:00:00.000000000'),
numpy.datetime64('2018-01-05T00:00:00.000000000'),
numpy.datetime64('2018-01-08T00:00:00.000000000'),
numpy.datetime64('2018-01-09T00:00:00.000000000'),
numpy.datetime64('2018-01-10T00:00:00.000000000'),
numpy.datetime64('2018-01-11T00:00:00.000000000'),
numpy.datetime64('2018-01-12T00:00:00.000000000'),
numpy.datetime64('2018-01-15T00:00:00.000000000'),
numpy.datetime64('2018-01-16T00:00:00.000000000'),
numpy.datetime64('2018-01-17T00:00:00.000000000'),
 
如何转化为python的daetime格式呢?
 
可以使用内置的:s.dt.to_pydatetime()
s为df的一列,也就是series数据格式b=list(df['日期'].dt.to_pydatetime())得到的是[datetime.datetime(2017, 12, 29, 0, 0),
datetime.datetime(2018, 1, 2, 0, 0),
datetime.datetime(2018, 1, 3, 0, 0),
datetime.datetime(2018, 1, 4, 0, 0),
datetime.datetime(2018, 1, 5, 0, 0),
datetime.datetime(2018, 1, 8, 0, 0),
datetime.datetime(2018, 1, 9, 0, 0),
datetime.datetime(2018, 1, 10, 0, 0),
datetime.datetime(2018, 1, 11, 0, 0),
datetime.datetime(2018, 1, 12, 0, 0),
datetime.datetime(2018, 1, 15, 0, 0)
为了不想要小时,分钟,秒的数据,可以清洗一下:
b=[i.strftime('%Y-%m-%d') for i in b]
 
得到:['2017-12-29',
'2018-01-02',
'2018-01-03',
'2018-01-04',
'2018-01-05',
'2018-01-08',
'2018-01-09',
'2018-01-10',
'2018-01-11',
'2018-01-12',
'2018-01-15',
'2018-01-16',
'2018-01-17',] 
  查看全部
dataframe的数据格式是这样子的:

d1.PNG

 
info看一下里面的数据类型:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 307 entries, 0 to 306
Data columns (total 7 columns):
日期 307 non-null datetime64[ns]
指数 307 non-null float64
成交额(亿元) 307 non-null float64
涨跌 307 non-null float64
涨跌额 307 non-null float64
转债数目 307 non-null float64
剩余规模 307 non-null float64
dtypes: datetime64[ns](1), float64(6)
memory usage: 16.9 KB

日期 307 non-null datetime64[ns]
 
然后转为list看看:
a=list(df['日期'].values)
如果使用上面的方法,返回的是这样的数据:
[numpy.datetime64('2017-12-29T00:00:00.000000000'),
numpy.datetime64('2018-01-02T00:00:00.000000000'),
numpy.datetime64('2018-01-03T00:00:00.000000000'),
numpy.datetime64('2018-01-04T00:00:00.000000000'),
numpy.datetime64('2018-01-05T00:00:00.000000000'),
numpy.datetime64('2018-01-08T00:00:00.000000000'),
numpy.datetime64('2018-01-09T00:00:00.000000000'),
numpy.datetime64('2018-01-10T00:00:00.000000000'),
numpy.datetime64('2018-01-11T00:00:00.000000000'),
numpy.datetime64('2018-01-12T00:00:00.000000000'),
numpy.datetime64('2018-01-15T00:00:00.000000000'),
numpy.datetime64('2018-01-16T00:00:00.000000000'),
numpy.datetime64('2018-01-17T00:00:00.000000000'),

 
如何转化为python的daetime格式呢?
 
可以使用内置的:s.dt.to_pydatetime()
s为df的一列,也就是series数据格式
b=list(df['日期'].dt.to_pydatetime())
得到的是
[datetime.datetime(2017, 12, 29, 0, 0),
datetime.datetime(2018, 1, 2, 0, 0),
datetime.datetime(2018, 1, 3, 0, 0),
datetime.datetime(2018, 1, 4, 0, 0),
datetime.datetime(2018, 1, 5, 0, 0),
datetime.datetime(2018, 1, 8, 0, 0),
datetime.datetime(2018, 1, 9, 0, 0),
datetime.datetime(2018, 1, 10, 0, 0),
datetime.datetime(2018, 1, 11, 0, 0),
datetime.datetime(2018, 1, 12, 0, 0),
datetime.datetime(2018, 1, 15, 0, 0)

为了不想要小时,分钟,秒的数据,可以清洗一下:
b=[i.strftime('%Y-%m-%d') for i in b]
 
得到:
['2017-12-29',
'2018-01-02',
'2018-01-03',
'2018-01-04',
'2018-01-05',
'2018-01-08',
'2018-01-09',
'2018-01-10',
'2018-01-11',
'2018-01-12',
'2018-01-15',
'2018-01-16',
'2018-01-17',]
 
 

kindle收不到python推送的附件,但是同邮件的客户端可以。求助。

李魔佛 回复了问题 • 2 人关注 • 1 个回复 • 1020 次浏览 • 2019-04-08 10:03 • 来自相关话题

python datetime模块:timestamp转为本地时间(东八区)

李魔佛 发表了文章 • 0 个评论 • 2292 次浏览 • 2019-04-04 15:15 • 来自相关话题

一般timestamp时间戳格式为10位,如果是13位,则需要除以1000,

1554369904000
为例,计算这个数字的本地时间。
 
如果使用
t=1554369904000
datetime.datetime.fromtimestamp(t/1000)
 
得到的是:
(2019, 4, 4, 17, 25, 4)
 
然而这个时间并不是我想要的,和我想要的时间差了8个时区。
 
那么可以使用
datetime.datetime.utcfromtimestamp(t/1000)
这个返回的就是我想要的时间了
(2019, 4, 4, 9, 25, 4)
 
 
引用:
timestamp转换为datetime
要把timestamp转换为datetime,使用datetime提供的fromtimestamp()方法:

>>> from datetime import datetime
>>> t = 1429417200.0
>>> print(datetime.fromtimestamp(t))
2015-04-19 12:20:00
注意到timestamp是一个浮点数,它没有时区的概念,而datetime是有时区的。上述转换是在timestamp和本地时间做转换。

本地时间是指当前操作系统设定的时区。例如北京时区是东8区,则本地时间:

2015-04-19 12:20:00
实际上就是UTC+8:00时区的时间:

2015-04-19 12:20:00 UTC+8:00
而此刻的格林威治标准时间与北京时间差了8小时,也就是UTC+0:00时区的时间应该是:

2015-04-19 04:20:00 UTC+0:00
timestamp也可以直接被转换到UTC标准时区的时间:

>>> from datetime import datetime
>>> t = 1429417200.0
>>> print(datetime.fromtimestamp(t)) # 本地时间
2015-04-19 12:20:00
>>> print(datetime.utcfromtimestamp(t)) # UTC时间
2015-04-19 04:20:00
 
  查看全部
一般timestamp时间戳格式为10位,如果是13位,则需要除以1000,

1554369904000
为例,计算这个数字的本地时间。
 
如果使用
t=1554369904000
datetime.datetime.fromtimestamp(t/1000)
 
得到的是:
(2019, 4, 4, 17, 25, 4)
 
然而这个时间并不是我想要的,和我想要的时间差了8个时区。
 
那么可以使用
datetime.datetime.utcfromtimestamp(t/1000)
这个返回的就是我想要的时间了
(2019, 4, 4, 9, 25, 4)
 
 
引用:
timestamp转换为datetime
要把timestamp转换为datetime,使用datetime提供的fromtimestamp()方法:

>>> from datetime import datetime
>>> t = 1429417200.0
>>> print(datetime.fromtimestamp(t))
2015-04-19 12:20:00
注意到timestamp是一个浮点数,它没有时区的概念,而datetime是有时区的。上述转换是在timestamp和本地时间做转换。

本地时间是指当前操作系统设定的时区。例如北京时区是东8区,则本地时间:

2015-04-19 12:20:00
实际上就是UTC+8:00时区的时间:

2015-04-19 12:20:00 UTC+8:00
而此刻的格林威治标准时间与北京时间差了8小时,也就是UTC+0:00时区的时间应该是:

2015-04-19 04:20:00 UTC+0:00
timestamp也可以直接被转换到UTC标准时区的时间:

>>> from datetime import datetime
>>> t = 1429417200.0
>>> print(datetime.fromtimestamp(t)) # 本地时间
2015-04-19 12:20:00
>>> print(datetime.utcfromtimestamp(t)) # UTC时间
2015-04-19 04:20:00