精华内容
下载资源
问答
  • 当商家收集到足够多的数据时,就可以对其进行亲和性分析,以确定哪些商品适合放在一起出售。 什么是亲和性呢,简单说就是物品之间的相似性或者说是相关性。比如说,一个去商场购物,买了苹果同时也买了香蕉,...

    背景介绍

    当顾客在购买一件商品时,商家可以趁机了解他们还想买什么,以便把多数顾客愿意同时购买的商品放到一起销售以提升销售额。当商家收集到足够多的数据时,就可以对其进行亲和性分析,以确定哪些商品适合放在一起出售。
    什么是亲和性呢,简单的说就是物品之间的相似性或者说是相关性。比如说,一个去商场购物,买了苹果的同时也买了香蕉,如果又买苹果又买香蕉的人比较多,那么我们把苹果和香蕉摆放在一起来销售,往往可以提高销量。这背后的思想就是人们经常购买同一件商品,下次大概率还是会继续购买。看似简单的思想,的确是很多线上和线下商品推荐服务的基础。
    之前的商品推荐工作,常常是人工在线下来完成的,费时费力,也没有很好地精准度。现在我们可以用数据驱动的方式来自动完成。节约成本,也提高了效率,下面我们来看看如何来做。


    数据准备和介绍

    import numpy as np
    dataset_filename = "affinity_dataset.txt"
    X = np.loadtxt(dataset_filename)
    n_samples, n_features = X.shape
    print("This dataset has {0} samples and {1} features".format(n_samples, n_features))

    结果是:This dataset has 100 samples and 5 features

    我们来解释下这个数据,看看顾客在前五次交易中都买了什么

    print(X[:5])
    [[ 0.  0.  1.  1.  1.]
     [ 1.  1.  0.  1.  0.]
     [ 1.  0.  1.  1.  0.]
     [ 0.  0.  1.  1.  1.]
     [ 0.  1.  0.  0.  1.]]

    竖着看,每一列分别表示一种商品的购买情况。分别是面包、牛奶、奶酪、苹果和香蕉。举个例子,第一行表示一个顾客,买了奶酪、苹果和香蕉。而没有买别的商品。每一行表示的是一次顾客购买行为。


    数据处理

    我们把数据特征打上标签,方便后面做处理:

    # The names of the features, for your reference.
    features = ["bread", "milk", "cheese", "apples", "bananas"]

    我们下面来做一个顾客既买苹果又买香蕉的支持度和置信度,这里支持度指的是,对于总体而言,有多少样本符合这个规则。置信度是:支持度/总体,比如说对于这个规则而言总是是买苹果也买香蕉+买苹果不买香蕉的总人数的和。即,只要他买苹果,就算做是总体中的一员。

    # How many of the cases that a person bought Apples involved the people purchasing Bananas too?
    # Record both cases where the rule is valid and is invalid.
    rule_valid = 0
    rule_invalid = 0
    for sample in X:
        if sample[3] == 1:  # This person bought Apples
            if sample[4] == 1:
                # This person bought both Apples and Bananas
                rule_valid += 1
            else:
                # This person bought Apples, but not Bananas
                rule_invalid += 1
    print("{0} cases of the rule being valid were discovered".format(rule_valid))
    print("{0} cases of the rule being invalid were discovered".format(rule_invalid))

    输出结果是

    21 cases of the rule being valid were discovered
    15 cases of the rule being invalid were discovered

    根据排列组合的知识,我们知道如果5种商品两两随机组合的话,一共有10种组合方式(C52),我们计算所有组合的置信度,并把排名前三的打印出来:

    import numpy as np
    dataset_filename = "affinity_dataset.txt"
    X = np.loadtxt(dataset_filename)
    n_samples, n_features = X.shape
    print("This dataset has {0} samples and {1} features".format(n_samples, n_features))
    
    # The names of the features, for your reference.
    features = ["bread", "milk", "cheese", "apples", "bananas"]
    
    from collections import defaultdict
    # Now compute for all possible rules
    valid_rules = defaultdict(int)
    invalid_rules = defaultdict(int)
    num_occurences = defaultdict(int)      #num_occurances represents the same number of rules
    
    for sample in X:   # (sample means record of buying fruit)
        for premise in range(n_features):
            if sample[premise] == 0: continue
            # Record that the premise was bought in another transaction
            num_occurences[premise] += 1
            for conclusion in range(n_features):
    
                '''
                根据排列组合的规则,我这里希望按照1,2,3,4; 2,3,4; 3,4;4这样的顺序进行比较。
                这样的话,比较10次,就遍历完所有的情况。基于此,有了最外层的if...else语句
                第一句话是为了让他按照我前面说的那个顺序走,后面的判断语句,保证不遍历超出范围
                '''
    
                conclusion = conclusion + premise  
                if conclusion < n_features:
    
    
    
                    if premise == conclusion:  # It makes little sense to measure if X -> X.
                        continue
                    if sample[conclusion] == 1:
                        # This person also bought the conclusion item
                        valid_rules[(premise, conclusion)] += 1
                    else:
                        # This person bought the premise, but not the conclusion
                        invalid_rules[(premise, conclusion)] += 1
                else:
                    continue
    
    
    support = valid_rules
    confidence = defaultdict(float)
    for premise, conclusion in valid_rules.keys():
        confidence[(premise, conclusion)] = valid_rules[(premise, conclusion)] / num_occurences[premise]
    
    

    最后我们来进行排序操作,打印前三个结果。先来看一下我们处理之后的结果都是什么样子的

    # 用于打印 Python 数据结构. 当你在命令行下打印特定数据结构时你会发现它很有用(输出格式比较整齐, 便于阅读).
    from pprint import pprint
    pprint(list(support.items()))
    [((0, 1), 14),
     ((1, 2), 7),
     ((3, 2), 25),
     ((1, 3), 9),
     ((0, 2), 4),
     ((3, 0), 5),
     ((4, 1), 19),
     ((3, 1), 9),
     ((1, 4), 19),
     ((2, 4), 27),
     ((2, 0), 4),
     ((2, 3), 25),
     ((2, 1), 7),
     ((4, 3), 21),
     ((0, 4), 17),
     ((4, 2), 27),
     ((1, 0), 14),
     ((3, 4), 21),
     ((0, 3), 5),
     ((4, 0), 17)]

    我们给输出定义一个函数形式,方面后面进行输出:
    因为我们之前写了一个feature列表,这样的话就很容易锁定到具体产品信息,只用一个列表就可以搞定,不用定义字典(这是一个不错的思路)

    def print_rule(premise, conclusion, support, confidence, features):
        premise_name = features[premise]
        conclusion_name = features[conclusion]
        print("Rule: If a person buys {0} they will also buy {1}".format(premise_name, conclusion_name))
        print(" - Confidence: {0:.3f}".format(confidence[(premise, conclusion)]))
        print(" - Support: {0}".format(support[(premise, conclusion)]))
        print("")

    示例输出:

    premise = 1
    conclusion = 3
    print_rule(premise, conclusion, support, confidence, features)

    Rule: If a person buys milk they will also buy apples
    - Confidence: 0.196
    - Support: 9

    然后进行排序操作,我们按照置信度大小进行排序,降序:

    # sort and print the first three result
    
    from operator import itemgetter
    sorted_confidence = sorted(confidence.items(), key=itemgetter(1), reverse=True)
    for index in range(3):
        print("Rule #{0}".format(index + 1))
        (premise, conclusion) = sorted_confidence[index][0]
        print_rule(premise, conclusion, support, confidence, features)

    结果如下:
    Rule #1
    Rule: If a person buys cheese they will also buy bananas
    - Confidence: 0.659
    - Support: 27

    Rule #2
    Rule: If a person buys bread they will also buy bananas
    - Confidence: 0.630
    - Support: 17

    Rule #3
    Rule: If a person buys cheese they will also buy apples
    - Confidence: 0.610
    - Support: 25

    从排序结果来看,“顾客买苹果,也会买奶酪”和“顾客买奶酪,也会买香蕉”,这两条规 则的支持度和置信度都很高。超市经理可以根据这些规则来调整商品摆放位置。例如,如果本周苹果促销,就在旁边摆上奶酪。或许可以提高超市销量哦。

    参考资料:
    《python数据挖掘入门与实践》
    数据集

    展开全文
  • 函数库是函数的组合,一般将一些功能相似的函数放在一起作为函数库,这种函数库通常叫做静态库,其链接方式是静态的。COM即组件对象模型,是一种集成技术,可以使程序在运行时各种不相关的软件程序混合在一起,而...
  • 函数库是函数的组合,一般将一些功能相似的函数放在一起作为函数库,这种函数库通常叫做静态库,其链接方式是静态的。COM即组件对象模型,是一种集成技术,可以使程序在运行时各种不相关的软件程序混合在一起,而...
  • 这些问题放在一个适当环境下讨论,书中提供了对复杂性理论(包括NP完全性和不可判定性)简短讨论。 第10章通过考查一般问题求解技巧来介绍算法设计。这一章含有大量实例。这里及后面各章使用了伪代码,...
  • 在机器学习中,无监督学习(Unsupervised learning)就是聚类,事先不知道样本的类别,通过某种办法,把相似的样本放在一起归位一类;而监督型学习(Supervised learning)就是有训练样本,带有属性标签,也可以理解...

    1、无监督学习和有监督学习

    机器学习中,无监督学习(Unsupervised learning)就是聚类,事先不知道样本的类别,通过某种办法,把相似的样本放在一起归位一类;而监督型学习(Supervised learning)就是有训练样本,带有属性标签,也可以理解成样本有输入有输出。

    所有的回归算法和分类算法都属于监督学习。回归(Regression)和分类(Classification)的算法区别在于输出变量的类型,定量输出称为回归,或者说是连续变量预测;定性输出称为分类,或者说是离散变量预测。

    2、贝叶斯分类

    2.1贝叶斯分类的基础——贝叶斯定理

    2.2朴素贝叶斯分类

    朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。通俗来说,就好比这么个道理,你在街上看到一个黑人,我问你你猜这哥们哪里来的,你十有八九猜非洲。为什么呢?因为黑人中非洲人的比率最高,当然人家也可能是美洲人或亚洲人,但在没有其它可用信息下,我们会选择条件概率最大的类别,这就是朴素贝叶斯的思想基础。

     朴素贝叶斯分类的正式定义如下:

    最关键的是如何求得第三步中的各个条件概率,我们可以这么做:

    因为分母对于所有类别为常数,因我们只要将分子最大化可。又因为各特征属性是条件独立的,所以有: 

    根据上述分析,朴素贝叶斯分类的流程可以由下图表示(暂时不考虑验证):

     第一阶段——准备工作阶段,这个阶段的任务是为朴素贝叶斯分类做必要的准备,主要工作是根据具体情况确定特征属性,并对每个特征属性进行适当划分,然后由人工对一部分待分类项进行分类,形成训练样本集合。这一阶段的输入是所有待分类数据,输出是特征属性和训练样本。这一阶段是整个朴素贝叶斯分类中唯一需要人工完成的阶段,其质量对整个过程将有重要影响,分类器的质量很大程度上由特征属性、特征属性划分及训练样本质量决定。

          第二阶段——分类器训练阶段,这个阶段的任务就是生成分类器,主要工作是计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率估计,并将结果记录。其输入是特征属性和训练样本,输出是分类器。这一阶段是机械性阶段,根据前面讨论的公式可以由程序自动计算完成。

          第三阶段——应用阶段。这个阶段的任务是使用分类器对待分类项进行分类,其输入是分类器和待分类项,输出是待分类项与类别的映射关系。这一阶段也是机械性阶段,由程序完成。

    2.3估计各个类别下特征属性划分的条件概率及Laplace校准

    这一节讨论P(a|y)的估计。

    由上文看出,计算各个类别下特征属性划分的条件概率P(a|y)是朴素贝叶斯分类的关键性步骤,当特征属性为离散值时,只要很方便的统计训练样本中各个特征属性划分在每个类别中出现的频率即可用来估计P(a|y),下面重点讨论特征属性是连续值的情况。

    当特征属性为连续值时,通常假定其值服从高斯分布(也称正态分布)。即:

       因此只要计算出训练样本中各个类别中此特征项划分的各均值和标准差,代入上述公式即可得到需要的估计值。均值与标准差的计算在此不再赘述。

          另一个需要讨论的问题就是当P(a|y)=0怎么办,当某个类别下某个特征项划分没有出现时,就是产生这种现象,这会令分类器质量大大降低。为了解决这个问题,我们引入Laplace校准,它的思想非常简单,就是对没类别下所有划分的计数加1,这样如果训练样本集数量充分大时,并不会对结果产生影响,并且解决了上述频率为0的尴尬局面。

    2.4朴素贝叶斯分类实例:检测SNS社区中不真实账号

    下面讨论一个使用朴素贝叶斯分类解决实际问题的例子,为了简单起见,对例子中的数据做了适当的简化。

          这个问题是这样的,对于SNS社区来说,不真实账号(使用虚假身份或用户的小号)是一个普遍存在的问题,作为SNS社区的运营商,希望可以检测出这些不真实账号,从而在一些运营分析报告中避免这些账号的干扰,亦可以加强对SNS社区的了解与监管。

          如果通过纯人工检测,需要耗费大量的人力,效率也十分低下,如能引入自动检测机制,必将大大提升工作效率。这个问题说白了,就是要将社区中所有账号在真实账号和不真实账号两个类别上进行分类,下面我们一步一步实现这个过程。

          首先设C=0表示真实账号,C=1表示不真实账号。

     1、确定特征属性及划分

          这一步要找出可以帮助我们区分真实账号与不真实账号的特征属性,在实际应用中,特征属性的数量是很多的,划分也会比较细致,但这里为了简单起见,我们用少量的特征属性以及较粗的划分,并对数据做了修改。

          我们选择三个特征属性:a1:日志数量/注册天数,a2:好友数量/注册天数,a3:是否使用真实头像。在SNS社区中这三项都是可以直接从数据库里得到或计算出来的。

    下面给出划分:a1:{a<=0.05, 0.05<a<0.2, a>=0.2},a2:{a<=0.1, 0.1<a<0.8, a>=0.8},a3:{a=0(不是),a=1(是)}。

     2、获取训练样本

          这里使用运维人员曾经人工检测过的1万个账号作为训练样本。

    3、计算训练样本中每个类别的频率

          用训练样本中真实账号和不真实账号数量分别除以一万,得到:

    4、计算每个类别条件下各个特征属性划分的频率

     5、使用分类器进行鉴别

          下面我们使用上面训练得到的分类器鉴别一个账号,这个账号使用非真实头像,日志数量与注册天数的比率为0.1,好友数与注册天数的比率为0.2。

    可以看到,虽然这个用户没有使用真实头像,但是通过分类器的鉴别,更倾向于将此账号归入真实账号类别。这个例子也展示了当特征属性充分多时,朴素贝叶斯分类对个别属性的抗干扰性。

    2.5分类器的评价

          首先要定义,分类器的正确率指分类器正确分类的项目占所有被分类项目的比率。

          通常使用回归测试来评估分类器的准确率,最简单的方法是用构造完成的分类器对训练数据进行分类,然后根据结果给出正确率评估。但这不是一个好方法,因为使用训练数据作为检测数据有可能因为过分拟合而导致结果过于乐观,所以一种更好的方法是在构造初期将训练数据一分为二,用一部分构造分类器,然后用另一部分检测分类器的准确率。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 之所以冒泡排序和选择排序放在一起,是因为二者实现代码很相似,而且都是最基本排序方式,非常容易理解和实现。当然,如果仅仅是为了讲述这两种排序方式,那也根本没必要写这篇博文了。和上篇博文一样,我会在...

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/20065107


    前言

        之所以把冒泡排序和选择排序放在一起,是因为二者的实现代码很相似,而且都是最基本的排序方式,非常容易理解和实现。当然,如果仅仅是为了讲述这两种排序方式,那也根本没必要写这篇博文了。和上篇博文一样,我会在冒泡排序和选择排序原始代码的基础上给出一些改进和优化,这才是本文的重点所在。

    原始冒泡排序

        冒泡排序的思想很简单,如果要求排序后序列中元素按照从小到大的顺序排列,则冒泡排序的步骤如下:

        1、依次比较序列中相邻的两个元素,将较大的放在后面,这样一趟比较后,最大的元素就放在了最后的一个位置;

        2、再依次比较相邻的两个元素,将第二大的元素最终放到倒数第二个位置;

        3、依次循环,直到最小的元素放在了第一个位置,排序完成。

        根据以上思想,很容易写出代码:

    /*
    冒泡排序后的顺序为从小到大
    */
    void Bubble_Sort(int *arr,int len)
    {
    	int i,j,exchange;
    	for(i=0;i<len-1;i++)
    		for(j=0;j<len-i-1;j++)
    			if(arr[j] > arr[j+1])
    			{
    				exchange = arr[j];
    				arr[j] = arr[j+1];
    				arr[j+1] = exchange;
    			}
    }

    改进冒泡排序 

        我们回过头来再来看上面冒泡排序的思想,无论原始序列的排序是怎样的(哪怕已经是从小到大排好的),它都要进行n-1趟比较,每趟比较又要进行n-i-1次相邻元素间的比较(i为从0开始计的第i趟比较),而实际上,很有可能还没有进行第n-1趟比较,已经完成了排序,这时候后面的几趟比较就显得多余了,基于此,我们可以做如下改进:设置一个标志位,如果某一趟有元素发生交换,则为true,继续下一趟比较,否则,说明排序已经完成,则标志位为false,退出循环。代码实现如下:

    /*
    冒泡排序后的顺序为从小到大
    */
    void Bubble_Sort(int *arr,int len)
    {
    	int i,j,exchange;
    	bool flag = true;   //增设标志位,判断是否已经完成排序
    	for(i=0; i<len-1 && flag; i++)
    	{
    		flag = false;
    		for(j=0;j<len-i-1;j++)
    			if(arr[j] > arr[j+1])
    			{	//如果本趟比较没有数据发生交换,说明排序已经完成
    				//则flag一直为false,从而退出循环,不再进行下一趟的比较
    				exchange = arr[j];
    				arr[j] = arr[j+1];
    				arr[j+1] = exchange;
    				flag = true;
    			}
    	}
    }

    直接选择排序

        直接选择排序的思想也很简单,以排序从小到大为例,如下:

        1、从第一个元素开始,选出一个最小的元素与第一个元素互换;

        2、继续从第二个元素开始,向后选出最小的元素,与第二个元素互换;

        3、依次循环执行,直到最大的元素放在了最后一个位置上,排序完成。

        我们可以将第一个元素分别与后面的元素进行比较,遇到更小的,就交换,这样一趟比较下来,第一个元素保存就是最小值,而后再从第二个元素开似乎,依次与后面的元素比较,遇到更小的,就交换,这样,第二趟比较下来,第二个元素保存的就是第二小的值。。。依次循环执行,直到完成排序。按照这样的思路,实现代码如下:

    /*
    第一种形式的选择排序
    选择排序后的顺序为从小到大
    */
    void Select_Sort1(int *arr,int len)
    {
    	int i,j;
    	for(i=0;i<len;i++)
    		for(j=i+1;j<len;j++)
    			if(arr[i] > arr[j])
    			{
    				int exchange = arr[i];
    				arr[i] = arr[j];
    				arr[j] = exchange;
    			}
    }

    改进选择排序

        但是我们上篇文章中提到过,在排序中应该尽量避免较多的和元素互换操作,而这里每比较一次,如果遇到更小的,就要互换一次元素。为了减少元素互换操作,我们可以在每次比较后不直接进行交换,将较小的元素的位置序号记录下来,这样一趟比较之后,就会得到最小元素的位置,如果最小值的位置发生了改变,再将该位置的元素与第一个元素互换,依次类推。。。这样每一趟比较完成后最多只需执行一次元素互换的操作。实现代码如下:

    /*
    第二种形式的选择排序,减少了元素互换的操作
    选择排序后的顺序为从小到大
    */
    void Select_Sort2(int *arr,int len)
    {
    	int i,j,min;
    	for(i=0;i<len;i++)
    	{
    		min = i;	//用来记录每一趟比较的最小值的位置
    		for(j=i+1;j<len;j++)
    			if(arr[min] > arr[j])
    				min = j;	 //仅记录最小值的位置
    		//如果最小值的位置发生了变化,
    		//则最后执行一次元素互换的操作
    		if(min != i)
    		{
    			int exchange = arr[i];
    			arr[i] = arr[min];
    			arr[min] = exchange;
    		}
    	}
    }

    总结

        冒泡排序和选择排序都是最基本的排序算法,平均时间复杂度都为O(n*n),排序元素个数较少时,适合使用,遇到大数据量时,最好选用其他排序算法。

    完整源码

        完整的C语言实现代码下载地址:http://download.csdn.net/detail/mmc_maodun/6970951




    展开全文
  • 类增加了,我们可以把相似的放在一起模块; 模块多了,我们将实现相似功能的模块放在一起,就产生了“包”。 包类似于文件夹、模块类似于文件,函数和语句类似于文件里的内容 *要点: <1>python程序由...

    目录

     

    一、模块化程序设计理念

    1、量变引起质变

    2、标准库模块

    3、为什么需要模块化?

    4、模块化编程的流程

    (1)设计API,进行功能描述;

    (2)编码实现API中描述的功能;

    (3)在模块中遍历测试代码,并消除全局代码;

    (4)使用私有函数实现不被外部客户端调用的模块函数

    5、模块的API和功能描述要点

    (1)API(Application Programing Interface)应用程序编程接口,用于描述模块中提供的函数和类的功能描述和使用方法描述;

    (2)可以通过__doc__来获得模块的文档字符串你的内容

    (3)当以个模块作为程序入口时,它的名字__name__ 的值为__main__,我们可以根据这个特点,将模块源代码文件中的测试代码进行独立处理

    二、模块的导入

    1、import语句的导入

    2、from···import导入

    3、动态导入

    (1)__import__()

    (2)importlib模块

    4、包(package)的使用

    三、sys.path和模块搜索路径

    四、模块的发布和安装

    1、模块的本地发布

    2、本地安装模块


    一、模块化程序设计理念

    1、量变引起质变

    程序越来越多,语句多了,我们会将实现同一个功能的语句封装到函数中,统一管理和调用,就产生了函数;

    随着函数和变量的增加,“物以类聚”,我们将同一类型对象的数据和行为,也就是变量和函数,放在一起管理,就产生了“类和对象”;

    类增加了,我们可以把相似的类放在一起模块;

    模块多了,我们将实现相似功能的模块放在一起,就产生了“包”。

    包类似于文件夹、模块类似于文件,函数和语句类似于文件里的内容

    *要点:
    <1>python程序由模块组成,一个模块对应python源文件,一般后缀名为:.py;

    <2>模块由语句组成,运行python程序时,按照模块中语句的顺序依次执行;

    <3>语句是python程序的构造单元,用于创建爱你对象、变量赋值、调用函数、控制语句等

    2、标准库模块

    模块分为标准库模块和用户自定义模块,类似于random模块、math模块、time模块、file模块、os模块

    另外,python还提供海量的第三方模块,使用方式和标准库类似,功能覆盖了我们能想象的所有领域,比如:科学计算、web开发、大数据、人工智能、图形系统

    3、为什么需要模块化?

    是为了后期的反复使用和搭建

    优势:
    (1)便于将一个任务分解成多个模块,实现团队协同开发;

    (2)实现代码复用。一个模块实现后,可以被反复调用;

    (3)可维护性增强

    4、模块化编程的流程

    (1)设计API,进行功能描述;

    #作为设计者,只需要把答题的设计框架设计出来,具体的实现由员工来做
    '''
           用于计算公司员工的薪资
    '''
    
    
    
    company = "小蜗公众号"
    
    def yearSalary(mothSalary):
        '''
        计算年薪,根据传入的月薪值,算出年薪
        :param mothSalary:
        :return:
        '''
        pass
    
    def daySalary(mothSalary):
        '''
        计算日薪
        :param mothSalary:
        :return:
        '''
        pass

    (2)编码实现API中描述的功能;

    #################实现######################
    
    company = "小蜗公众号"
    
    def yearSalary(mothSalary):
        '''
        计算年薪,根据传入的月薪值,算出年薪
        :param mothSalary:
        :return:
        '''
        return mothSalary * 12
    
    
    
    
    def daySalary(mothSalary):
        '''
        计算日薪
        :param mothSalary:
        :return:
        '''
        return mothSalary / 22.5

    (3)在模块中遍历测试代码,并消除全局代码;

    在本模块中测试代码

    
    if __name__ == "__main__":        #测试代码
        print(yearSalary(5000))
        #60000
    
        print(daySalary(3000))
        #133.33333333333334

    (4)使用私有函数实现不被外部客户端调用的模块函数

    5、模块的API和功能描述要点

    (1)API(Application Programing Interface)应用程序编程接口,用于描述模块中提供的函数和类的功能描述和使用方法描述;

    (2)可以通过__doc__来获得模块的文档字符串你的内容

    import Salary
    
    print(Salary.__doc__)
    
    
    '''
    
           用于计算公司员工的薪资
           
           
    '''
    
    print(Salary.daySalary.__doc__)
    
    '''
        计算日薪
        :param mothSalary:
        :return:
    '''
    
    print(Salary.__name__)
    #Salary
    
    
    ##########测试代码##########
    

    (3)当以个模块作为程序入口时,它的名字__name__ 的值为__main__,我们可以根据这个特点,将模块源代码文件中的测试代码进行独立处理

    上面第四点的第三点里有代码

    二、模块的导入

    在主目录下建立了a包,a包下面建立了aa子包、module__A1、module__A2、module__A3;aa子包里建立了module__AA.py文件;主目录下建立了b包,b包里建立了module__B1、module__B2。如下图所示

    module__AA.py文件的内容如下所示

    print("AA,2021.04.08")
    
    def fun_AA():
        print("in fun__AA")

    1、import语句的导入

    语法:
    import 模块名——导入一个模块

    import 模块1,模块2——导入多个模块

    import模块名 as 模块别名——导入模块并使用新名字

    import a.aa.module__AA
    #AA,2021.04.08 打印出了模块的内容
    import a.aa.module__AA
    a.aa.module__AA.fun_AA()
    
    AA,2021.04.08
    in fun__AA
    

    import加载的模块分为四种:

    a. 使用python编写的代码(.py)文件;

    b. 已被编译为共享库或者DLL的C或C++扩展;

    c.包好一组模块的包;

    d. 使用C编写并连接到python解释器的内置模块

    要点:我们一般通过import语句实现模块的导入和使用,本质是上是使用了内置函数__import__()方法,我们导入的模块是一个对象

    2、from···import导入

    使用from···impor是导入了模块中的成员

    基本的语法是:from 模块名 import ···

    可以类比为:import导入的是文件——如果要使用模块里的方法,则需要写模块名;from ··· import··· 导入的是文件的内容:我们可以直接写文件下的内容

    from a.aa.module__AA import fun_AA
    fun_AA()
    #in fun__AA
    
    from a.aa import module__AA
    module__AA.fun_AA()
    #in fun__AA

    3、动态导入

    (1)__import__()

    import语句实质上是调用内置函数__import__(),我们可以通过它实现动态导入,给__import__()动态传递不同的参数值,就能导入不同的模块。不建议使用这种方法

    import math
    
    print(id(math))
    #2604518870216
    
    print(type(math))
    #<class 'module'>
    
    import math, turtle
    print(id(math))
    #2604518870216
    #这样个id是相同的,也就是说,一个模块无论被导入多少次,这个模块在整个解释器进程中有且仅有一个实例对象
    
    import math as m #给math起了一个新名字
    
    print(math.sin(3.14))
    #0.0015926529164868282
    
    s = "math"
    m = __import__(s)
    #此步骤类似于前面的 import math as m
    m.sin(3.14)
    #0.0015926529164868282
    
    import importlib
    a = importlib.import_module("math") 
    
    print(a.pi)
    #3.141592653589793
    

    (2)importlib模块

    例1:

    主文件下建立test02文件,文件内容如下:

    import math
    
    print("in test02, 模块被加载···")
    
    
    def t1():
        pass
    import test02
    import test02
    import test02
    #此例子说明,模块只需要被导入一次,无需多次导入
    
    
    print("###############################")
    
    import importlib
    importlib.reload(test02)  #importlib 里面的import_module可以帮助我们加载模块,reload模块可以帮我们重新加载模块
    '''
    ###############################
    in test02, 模块被加载··· 
    实现了重新加载
    '''
    

     例2:

    import a.aa.module__AA
    #AA,2021.04.08 打印出了模块的内容
    
    import importlib
    from a.aa import module__AA
    importlib.reload(module__AA)
    #AA,2021.04.08
    #写这个例子是想说明,import a.aa.module__AA 等同于 from a.aa import module__AA
    

    4、包(package)的使用

    (1)包的概念和结构

    <1>概念:当一个项目有很多模块时,就需要进行组织管理,将功能相似的模块放在一起,形成了“包”。本质上来讲,“包”就是一个必须有__init__.py的文件——这是包与文件夹最大的区别。

    <2>要点:

    包西面可以包含“模块(module)”,也可以包含“子包(subpackage)”。就像文件夹下面可以有文件,也可以有子文件夹一样

    (2)pycharm中创建包

    (3)导入包操作和本质

    导入包的本质其实是“导入了包的__init__.py文件”。也就是说,"import pack1"意味着执行了包pack1下面的__init__.py文件。这样,在__init__.py中可以批量导入我们需要的模块,而不需要一个个导入

    a包下的__init__.py文件里面的内容如下所示:

    import math
    import turtle
    
    print("导入a包")
    

    在moudle_b1里面输入一下内容 

    import a
    #导入a包
    #意味着输入了a包下的__init__.py文件中的内容
    
    
    #尝试导入a包里面的math方法,由于math方法是从a包里来的
    import a
    print(a.math.pi)
    #3.141592653589793 math并不是独立模块,而仅仅是a里面的一个方法
    
    import math
    print(math.pi)
    print(id(a.math))
    #2834350214504
    print(id(math))
    #2834350214504
    

    (4)虽然调用包的模块是指就是在调用__init__.py文件,可以在该文件中定义函数和类,但是我们尽量要求__init__.py简单,以保证其执行的性能

    __init__.py的三个核心作用:

    ·作为包的标识,不能删除;

    ·用来实现模糊导入;

    ·导入包的实质是执行__init__.py文件,可以在__init__.py文件中做这个包的初始化以及需要同一执行的代码,批量导入

    import * 方法的使用,*不会具体得写那个模块或方法,可以在__init__.py文件中,通过__all__来定义

    a包的__init__.py文件里写入一下内容:

    import math
    import turtle
    
    print("导入a包")
    
    
    __all__ = ["module_A1", "module_A2"]
    #不要module_A3
    
    from a import *
    module_A1.fun_A1()
    '''
    导入a包
    '''
    

    包内引用

    from ··import module_A1  #··表示上级目录

    from ·import moudule_A2 #表示同级目录

    from ··import module_A1  #··表示上级目录
    
    from ·import moudule_A2 #表示同级目录

    三、sys.path和模块搜索路径

    当我们导入某个模块文件的时候,python解释器要去哪里找?一般来说会按照以下路径寻找模块文件;

    1、内置模块;

    2、当前目录;

    3、程序的主目录;

    4、pythonpath目录(如果已经设置了)——pythonpath环境变量

    5、标准链接目录;

    6、第三方库目录;

    7、.pth文件的内容(如果存在的话)——在pycharm里面指向的site—packages里面设置,右击创建文本文档,名字改为.pth. 。打开文档之后写入:

    g:\a

    g:\b

    g:\c

    8、sys.path.append()临时添加的目录

    import sys
    sys.path.append("d:/")
    print(sys.path)
    
    
    'D:\\developer_tools\\pycharm\\模块'      先从当前目录找,当前的目录就是主目录  'D:\\developer_tools\\pycharm\\模块'      到主目录里找   
    'D:\\PyCharm\\helpers\\pycharm_display'   环境变量里找  
     'D:\\anaconda3\\python37.zip', 'D:\\anaconda3\\DLLs', 'D:\\anaconda3\\lib', 'D:\\anaconda3'                           anaconda里面的python里找
    'D:\\developer_tools\\pycharm\\模块\\venv'pycharm里面的虚拟环境----标准库里找
    'D:\\developer_tools\\pycharm\\模块\\venv\\lib\\site-packages'第三方下载 
    'D:\\developer_tools\\pycharm\\模块\\venv\\lib\\site-packages\\setuptools-40.8.0-py3.7.egg'
                                             .pth文件里找  
    'D:\\PyCharm\\helpers\\pycharm_matplotlib_backend'
    'd:/'                                     最后在临时添加的路径里找
                                                                                                                                                                                                                                                                                                                                     
    
    

    四、模块的发布和安装

    1、模块的本地发布

    建立字典,字典里面建立包,包下面建立模块,在包同级下建立setup的.py文件,里面写关于安装的内容;

    在math3字典下创建了“西电”包(内含demo1和的模模块)和setup文件——写明了安装内容

    在setup文件里写如下内容

    from distutils.core import setup
    
    setup(
        name='西电',  #对外我们模块的名字
        version='1.0', #版本号
        description='这是第一个对外发布的模块,测试哦', #描述
        author='littel star', #作者
        author_email='852989197.qq.com',
        py_modules=['西电.demo1', '西电.demo2'] #要发布的模块
    )

     demo1如下:

    def add():
        print("add")

    demo2如下:

    def multiple():
        print("multiple")

     在字典处右击“open in terminal”,打开终端页面后输入“python setup.py sdist”,会生成dist这个字典,里面有我们要上传的包的压缩包

    2、本地安装模块

    在字典math3里面打开终端,输入python setup.py install 即可安装成功

    有时候下载的内容并不在我们当前的解释器环境中,需要自行他调整

    在setting里面的project interpreter里面更改。下载好以后,在python终端里会提示下载模块所在位置,更给为此位置即可。

    展开全文
  • 之所以归并排序和快速排序放在一起探讨,很明显两者有一些相似之处:这两种排序算法都采用了分治思想。下面来逐个分析其实现思想。 归并排序 实现思想 归并含义很明显就是将两个或者两个以上有序表组合...
  • 简单说,分类就是向事物分配标签,聚类就是将相似的事物放在一起。 先上一张对比图做以简单了解 举个例子 假设有一批人的年龄的数据,大致知道其中有一堆少年儿童,一堆青年人,一堆老年人。 聚类就是自动发现这三...
  • 相信大家一看到数组、动态数组和集合放在一起讨论时候最深刻印象就是他们非常的相似而且都是用来存储数据的。说是非常的相似但还是有一些差别,就是这些差别让它们各显神通。在不同情况下选择其中一个进行...
  • String用法

    2018-04-12 20:31:39
    string类声明string类本不是STL的容器,但是它与STL容器有着很多相似的操作,因此,string放在这里一起进行介绍。 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心...
  • 关于string 简单应用

    2018-04-30 10:47:00
    string类本不是STL的容器,但是它与STL容器有着很多相似的操作,因此,string放在这里一起进行介绍。之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、...
  • 相同放在一起,不同数不放在一起。 *注意:整个程序时间复杂度不在意,主要Q() 调用满足O(nlogn)就可以。不需要完整代码,大纲和主要步骤即可。感谢! e.g. input: A[] = {1, 2, 1, 2, 1, 2} ...
  • java 对象与类

    2013-03-18 15:07:25
    面向对象编程与面向过程编程不同地方在于,面向对象总是把数据和操作数据方法放在一起,所有与数据相关操作都在当前类中提供。相似之处在于面向对象编程操作数据方法内部实现使用时面向过程编程方式。...
  • 用 Python 进行系统聚类分析

    千次阅读 2020-07-22 21:39:36
    在进行机器学习时,我们往往要对数据进行聚类分析,聚类,说白了就是把相似的样品点/数据点进行归类,相似度高的样品点会放在一起,这样一个样本就会被分成几类。而聚类分析也有很多种方法,比如分解...
  • String用法详解

    万次阅读 多人点赞 2018-04-05 16:15:51
    string类声明string类本不是STL的容器,但是它与STL容器有着很多相似的操作,因此,string放在这里一起进行介绍。 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心...
  • k-Means聚类算法实现

    2018-10-26 16:20:40
    首先来说聚类它是一种无监督学习方式,输入的数据集实例中并没有标签,也没有指定的学习任务,算法的结果是产生几个簇,相似的数据实例放在一起,而这个相似度的度量,正是算法的核心,本文采用的是基于距离的...
  • 一次Mariadb死锁排查过程回顾

    千次阅读 2020-02-29 18:14:21
    场景 在使用某个平台时候,有些页面发现长时间,部分数据...既然整体功能是正常,只有部分页面出现问题,而且都是实时数据无法显示,怀疑是同一个地方出现问题,于是接口放在一起发现共同点。 都是timeout...
  • android平台也提供了很多API供开发者使用,请按示例图: 首先,介绍一下通过http包工具进行通信,分get和post两种方式,两者区别是: 1,post请求发送数据到服务器端,而且数据放在html header中一起发送到...
  • JAVA入门笔记

    2021-03-06 16:06:37
    实现:封装是通过一组数据和与数据有关操作集合放在一起形成对象。 (2).目的:防止非法访问,用户只能用对象提供接口利用服务。 (3).封装后得到基本单元是类。 继承: (1).为了提高代码重用性。 (2)....
  • 聚类分析

    2021-04-16 13:13:29
    比如人和其他动物放在一起比较,你可以很轻松地找到一些判断特征,比如肢体、嘴巴、耳朵、皮毛等等,根据判断指标之间差距大小划分出某一类为人,某一类为狗,某一类为鱼等等,这就是聚类。 K-means 聚类分析...
  • 他们放在一起原因是,网上太多资料,将散列和加密概念混为一谈,误导性极大。 由于编码/解码运算和上述二者有一定的相似之处,因此放在这里一并讲述。 注:本文中,为了表述严谨,所有“位”代表是...
  • 机器学习算法分类

    2020-12-14 23:15:20
    机器学习算法分类监督学习无监督学习强化学习 监督学习 ...【定义】 在机器学习中,无监督学习就是聚类,事先不知道样本的类别,通过某种办法,把相似的样本放在一起归位一类。 目标值 : 无 —— 无监
  • 【C++】string类

    2020-02-05 21:19:43
    string类本不是STL的容器,但是它与STL容器有着很多相似的操作,因此,string放在这里一起进行介绍。 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、...
  • STLstring详解

    2018-07-09 20:21:00
    string类本不是STL的容器,但是它与STL容器有着很多相似的操作,因此,string放在这里一起进行介绍。 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、...
  • 多任务学习算法及代码实现

    千次阅读 2018-08-21 23:58:14
    定义:基于共享表示(shared representation),多个相关任务放在一起学习一种机器学习方法。 也就是说,基于某些层参数共享,训练几个具有相似任务,然后给出每个任务分类结果。 举例:比...
  • 封装实现了把数据和操作这些数据代码包装成为 一个对象(即离散部件),而数据和操作细节(方法)隐藏起来。如果增加某些限制,使 得对数据访问可按照统一方式进行,那些能比较容易地产生更为强壮代码。 ...
  • 【C++】STL常用容器总结之十二:string类

    万次阅读 多人点赞 2016-08-25 13:02:43
    13、string类声明string类本不是STL的容器,但是它与STL容器有着很多相似的操作,因此,string放在这里一起进行介绍。 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必...

空空如也

空空如也

1 2 3 4 5
收藏数 95
精华内容 38
关键字:

把数据相似的放在一起