数据分析学习笔记part_2

数据分析


 

Lesson 2 : Python 入门

数据类型和运算符

  • 数据类型和运算符

    • 数据类型:整型、浮点型、布尔型、字符串、列表、元组、集合、字典

    • 运算符:算术、赋值、比较、逻辑、成员、恒等运算符

    • 内置函数、复合数据结构、类型转换

    • 空格和样式指南

  • 算数运算符

    • + 加

    • - 减

    • * 乘

    • / 除

    • % 取模(相除后的余数)

    • ** 取幂(注意 ^ 并不执行该运算,可能在其他语言中见过这种情形)

    • // 相除后向下取整到最接近的整数

      练习:平均电费

      1. 我在过去三个月的电费是 23 美元、32 美元和 64 美元。这三个月的每月平均电费是多少?请写一个表达式来计算均值,并使用 print() 查看结果。

      # Write an expression that calculates the average of 23, 32 and 64.
      # Place the expression in this print statement.
      print((23 + 32 + 64) / 3)

       

      1. 在这道练习中,将为铺瓦工执行一些运算。地面的两个部分需要贴砖。一个区域是宽 9 块砖,长 7 块砖,另一个区域是宽 5 块砖,长 7 块砖。一包砖有 6 块。需要多少块砖?如果购买17包砖,每包有6块。剩下多少块砖?

        # Fill this in with an expression that calculates how many tiles are needed.
        print(9 * 7 + 5 * 7)
        ​
        # Fill this in with an expression that calculates how many tiles will be left over.
        print(17 * 6 - 9 * 7 - 5 * 7)

         

  • 变量和赋值运算

  • 变量1

    • mv_population = 74728

    • mv_population 是变量,负责存储 74728 的值。该表达式将右侧的项目赋值给左侧的名称,实际上和数学等式有所不同,因为 74728 不存储 mv_population 的值。

    • 在任何情况下,无论左侧项是什么,在赋值后,都是右侧值的变量名称。一旦将变量值赋值给变量名称,便可以通过该名称访问这个值。

  • 变量2

    • x = 3
      y = 4
      z = 5
      #两个表达式在赋值方面是对等的
      x, y, z = 3, 4, 5
    • 但是,在大多数情况下,上面的表达式并不是很好的赋值方式,因为变量名称应该要能够描述所存储的值才能体现意义。

    • 命名变量需要注意:

      1. 只能在变量名称中使用常规字母、数字和下划线。不能包含空格,并且需要以字母或下划线开头。

      2. 不能使用保留字或内置标识符,它们在 Python 中具有重要含义,python 保留字列表请参阅此处。创建对值清晰描述的名称可以帮助避免使用这些保留字。下面是这些保留字的简要表格。

      3. 在 python 中,变量名称的命名方式是全部使用小写字母,并用下划线区分单词。

  • 赋值运算符

  • =

 

  • 整数和浮点数

  • 数字值可以用到两种 python 数据类型:

    • int - 表示整数值

    • float - 表示小数或浮点数值

      x = int(4.7)   # x is now an integer 4
      y = float(4)   # y is now a float of 4.0

       

    • 可以通过以下语法创建具有某个数据类型的值:

      x = int(4.7)   # x is now an integer 4
      y = float(4)   # y is now a float of 4.0

       

    • 可以使用函数 type 检查数据类型:

      >>> print(type(x))
      int
      >>> print(type(y))
      float

       

  • PEP8 指南

  • 布尔型运算符、比较运算符和逻辑运算符

  • 布尔数据类型存储的是值 True 或 False,通常分别表示为 1 或 0

    通常有 6 个比较运算符会获得布尔值:

    • 比较运算符

      符号使用情况布尔型运算符
      5 < 3 False 小于
      5 > 3 True 大于
      3 <= 3 True 小于或等于
      3 >= 5 False 大于或等于
      3 == 5 False 等于
      3 != 5 True 不等于
    • 三个逻辑运算符

      5 < 3 and 5 == 5Falseand - 检查提供的所有语句是否都为 True
      5 < 3 or5 == 5 True or - 检查是否至少有一个语句为 True
      not 5 < 3 True not - 翻转布尔值
  • 字符串

    • 在 python 中,字符串的变量类型显示为 str。可以使用双引号 " 或单引号 ' 定义字符串。

    >>> my_string = 'this is a string!'
    >>> my_string2 = "this is also a string!!!"

     

    • 可以在字符串中使用 \(转义字符),以包含其中一种引号:

    >>> this_string = 'Simon\'s skateboard is in the garage.'
    >>> print(this_string)
    #output
    Simon's skateboard is in the garage.

     

    • 如果不使用 \,注意我们遇到了以下错误:

    >>> this_string = 'Simon's skateboard is in the garage.'
    #output ERROR
    File "<ipython-input-20-e80562c2a290>", line 1
        this_string = 'Simon's skateboard is in the garage.'
                             ^
    SyntaxError: invalid syntax

     

  • 类型和类型转换

    • 常见的四种数据类型:

      1. 整型

      2. 浮点型

      3. 布尔型

      4. 字符串

  • 字符串方法

    • 方法就像某些已经见过的函数

      1. len("this")

      2. type(12)

      3. print("Hello world")

    • type 和 print 函数可以接收字符串、浮点型、整型和很多其他数据类型的参数,函数 len 也可以接受多种不同数据类型的参数

       

  • 列表和成员运算符

    • 列表:可以使用方括号创建列表。列表可以包含我们到目前为止所学的任何数据类型并且可以混合到一起。

      lst_of_random_things = [1, 3.4, 'a string', True]

       

    • 列表切片:我们可以使用切片功能从列表中提取多个值。在使用切片功能时,务必注意,下限索引包含在内上限索引排除在外

      >>> lst_of_random_things = [1, 3.4, 'a string', True]
      >>> lst_of_random_things[1:2]
      [3.4]

       

    • 列表里还是不在列表里?我们还可以使用 in 和 not in 返回一个布尔值,表示某个元素是否存在于列表中,或者某个字符串是否为另一个字符串的子字符串。

      >>> 'this' in 'this is a string'
      True
      >>> 'in' in 'this is a string'
      True
      >>> 'isa' in 'this is a string'
      False
      >>> 5 not in [1, 2, 3, 4, 6]
      True
      >>> 5 in [1, 2, 3, 4, 6]
      False

       

    • 可变性和顺序可变性是指对象创建完毕后,我们是否可以更改该对象。如果对象(例如列表或字符串)可以更改,则是可变的。但是,如果无法更改对象以创建全新的对象(例如字符串),则该对象是不可变的

      >>> my_lst = [1, 2, 3, 4, 5]
      >>> my_lst[0] = 'one'
      >>> print(my_lst)
      ['one', 2, 3, 4, 5]

       

      字符串和列表都是有序的。

  • 使用的列表函数

    • len() 返回列表中的元素数量。

    • max() 返回列表中的最大元素。最大元素的判断依据是列表中的对象类型。数字列表中的最大元素是最大的数字。字符串列表中的最大元素是按照字母顺序排序时排在最后一位的元素。因为 max() 函数的定义依据是大于比较运算符。如果列表包含不同的无法比较类型的元素,则 max() 的结果是 undefined。

    • min() 返回列表中的最小元素。它是 max() 函数的对立面,返回列表中的最小元素。

    • sorted() 返回一个从最小到最大排序的列表副本,并使原始列表保持不变。

    • Join ()是一个字符串方法,将字符串列表作为参数,并返回一个由列表元素组成并由分隔符字符串分隔的字符串。

      new_str = "\n".join(["fore", "aft", "starboard", "port"])
      print(new_str)
      #output
      fore
      aft
      starboard
      port

       

    • 我们还可以在 .join 中使用其他字符串作为分隔符。以下代码使用的是连字符。

      name = "-".join(["García", "O'Kelly"])
      print(name)
      #output
      García-O'Kelly

       

  • append 会将元素添加到列表末尾。

  • 元组

    • 元组是另一个实用容器。它是一种不可变有序元素数据类型。通常用来存储相关的信息。

      location = (13.4125, 103.866667)
      print("Latitude:", location[0])
      print("Longitude:", location[1])

       

    • 元组和列表相似,它们都存储一个有序的对象集合,并且可以通过索引访问这些对象。但是与列表不同的是,元组不可变,你无法向元组中添加项目或从中删除项目,或者直接对元组排序。

    • 元组还可以用来以紧凑的方式为多个变量赋值。

      dimensions = 52, 40, 100
      length, width, height = dimensions
      print("The dimensions are {} x {} x {}".format(length, width, height))

       

  • 集合

    • 集合是一个包含唯一元素的可变无序集合数据类型。集合的一个用途是快速删除列表中的重复项。

      numbers = [1, 2, 6, 3, 1, 1, 6]
      unique_nums = set(numbers)
      print(unique_nums)
      #output
      {1, 2, 3, 6}

       

    • 集合和列表一样支持 in 运算符。和列表相似,你可以使用 add 方法将元素添加到集合中,并使用 pop 方法删除元素。但是,当你从集合中拿出元素时,会随机删除一个元素。注意和列表不同,集合是无序的,因此没有“最后一个元素”。

      fruit = {"apple", "banana", "orange", "grapefruit"}  # define a set
      ​
      print("watermelon" in fruit)  # check for element
      ​
      fruit.add("watermelon")  # add an element
      print(fruit)
      ​
      print(fruit.pop())  # remove a random element
      print(fruit)
      ​
      #output
      False
      {'grapefruit', 'orange', 'watermelon', 'banana', 'apple'}
      grapefruit
      {'orange', 'watermelon', 'banana', 'apple'}

       

  • 字典和恒等运算符

    • 字典

      • 字典是可变数据类型,其中存储的是唯一键到值的映射。下面是存储元素和相应原子序数的字典。

        elements = {"hydrogen": 1, "helium": 2, "carbon": 6}

         

      • 字典的键可以是任何不可变类型,例如整数或元组,而不仅仅是字符串。甚至每个键都不一定要是相同的类型!我们可以使用方括号并在括号里放入键,查询字典中的值或向字典中插入新值。

        print(elements["helium"])  # print the value mapped to "helium"
        elements["lithium"] = 3  # insert "lithium" with a value of 3 into the dictionary

         

      • 我们可以像检查某个值是否在列表或集合中一样,使用关键字 in 检查值是否在字典中。字典有一个也很有用的相关方法,叫做 get。get 会在字典中查询值,但是和方括号不同,如果没有找到键,get 会返回 None(或者你所选的默认值)。

        print("carbon" in elements)
        print(elements.get("dilithium"))
        #output
        True
        None

         

    • 恒等运算符

      • 关键字运算符is检查两边是否恒等is not检查两边是否不恒等

        关键字运算符
        is 检查两边是否恒等
        is not 检查两边是否不恒等
      • 可以使用运算符 is 检查某个键是否返回了 None。或者使用 is not 检查是否没有返回 None。

        n = elements.get("dilithium")
        print(n is None)
        print(n is not None)
        #output
        True
        False

         

  • 复合数据结构

    • 我们可以在其他容器中包含容器,以创建复合数据结构。例如,下面的字典将键映射到也是字典的值!

      elements = {"hydrogen": {"number": 1,
                               "weight": 1.00794,
                               "symbol": "H"},
                    "helium": {"number": 2,
                               "weight": 4.002602,
                               "symbol": "He"}}

       

  • 我们可以如下所示地访问这个嵌套字典中的元素。

    helium = elements["helium"]  # get the helium dictionary
    hydrogen_weight = elements["hydrogen"]["weight"]  # get hydrogen's weight

     

控制流

  • 条件语句

  • If 语句

    • if 语句是是一种条件语句,根据条件为 true 还是 false 运行或执行相关代码。

      if phone_balance < 5:
          phone_balance += 10
          bank_balance -= 10

       

      1. if 语句以关键字 if 开始,然后是要检查的条件,在此例中是 phone_balance < 5,接着是英文冒号。条件用布尔表达式指定,结果为 True 或 False。

      2. 这行之后是一个条件为 true 时将执行的缩进代码块。在此例中,仅在 phone_balance 小于 5 时才执行使 phone_balance 递增和使 bank_balance 递减的行。如果不小于 5,这个 if 块中的代码将被跳过。

    • If 、 Elif 、Else除了 if 条件之外,if 语句经常还会使用另外两个可选条件。

      if season == 'spring':
          print('plant the garden!')
      elif season == 'summer':
          print('water the garden!')
      elif season == 'fall':
          print('harvest the garden!')
      elif season == 'winter':
          print('stay indoors!')
      else:
          print('unrecognized season')

       

      1. ifif 语句必须始终以 if 条件开始,其中包含第一个要检查的条件。如果该条件为 True,Python 将运行这个 if 块中的缩进代码,然后跳到 if 语句之后的剩余代码。

      2. elifelif 条件用来检查其他条件(前提是 if 语句中之前的条件结果为 False)。可以从示例中看出,可以使用多个 elif 块处理不同的情形。

      3. else:最后是 else 条件,它必须位于 if 语句的末尾。该条件语句不需要条件。如果 if语句中所有前面的语句结果都为 False 时,将运行 else 块中的代码。

 

  • 条件布尔表达式

    • If 语句有时候会使用更加复杂的条件布尔表达式。可能包括多个比较运算符、逻辑运算符,甚至包括算式。

      if 18.5 <= weight / height**2 < 25:
          print("BMI is considered 'normal'")
      ​
      if is_raining and is_sunny:
          print("Is there a rainbow?")
      ​
      if (not unsubscribed) and (location == "USA" or location == "CAN"):
          print("send email")

       

    • 对于非常复杂的条件,你可能需要结合使用 andor 和 not。使用括号可以使运算符组合更清晰。

      无论是简单还是复杂的条件,if 语句中的条件都必须是结果为 True 或 False 的布尔表达式,该值决定了 if 语句中的缩进代码块是否执行。

    • 在为 if 语句编写布尔表达式时,需要注意以下几个事项。

      1. 请勿使用 True 或 False 作为条件

        # Bad example
        if True:
            print("This indented code will always get run.")

         

        虽然“True”是一个有效的布尔表达式,但不是有用的条件,因为它始终为 True,因此缩进代码将始终运行。同样,if False 也不应使用,该 if 语句之后的语句将从不运行。

        # Another bad example
        if is_cold or not is_cold:
            print("This indented code will always get run.")

         

        同样,使用你知道将始终结果为 True 的条件(例如上述示例)也是毫无用途的。布尔表达式只能为 True 或 False,因此 is_cold 或 not is_cold 将始终为 True,缩进代码将始终运行。

      2. 在使用逻辑运算符编写表达式时,要谨慎

        逻辑运算符 andor 和 not 具有特定的含义,与字面英文意思不太一样。确保布尔表达式的结果和你预期的一样。

        # Bad example
        if weather == "snow" or "rain":
            print("Wear boots!")

         

        这段代码在 Python 中是有效的,但不是布尔表达式,虽然读起来像。原因是 or 运算符右侧的表达式 "rain" 不是布尔表达式,它是一个字符串。

      3. 请勿使用 == True 或 == False 比较布尔变量

        这种比较没必要,因为布尔变量本身是布尔表达式。

        # Bad example
        if is_cold == True:
            print("The weather is cold!")

         

        这是一个有效的条件,但是我们可以使用变量本身作为条件,使代码更容易读懂,如下所示。

        # Good example
        if is_cold:
            print("The weather is cold!")

         

        如果你想检查布尔表达式是否为 False,可以使用 not 运算符。

    • 真价值测试

      • 如果我们在if 语句中使用非布尔对象代替布尔表达式,Python 将检查其真假值,判断是否运行缩进代码。默认情况下,Python 中对象的真假值被视为 True,除非在文档中被指定为 False。

        以下是在 Python 中被视为 False 的大多数内置对象:

        • 定义为 false 的常量:None 和 False

        • 任何数字类型的零:00.00jDecimal(0)Fraction(0, 1)

        • 空序列和空集合:””()[]{}set()range(0)

  • For 循环

    • Python 有两种类型的循环:for 循环和 while 循环。for 循环用来遍历可迭代对象。

    可迭代对象是每次可以返回其中一个元素的对象,包括字符串、列表和元组等序列类型,以及字典和文件等非序列类型。可以使用迭代器和生成器定义可迭代对象。

      # iterable of cities
      cities = ['new york city', 'mountain view', 'chicago', 'los angeles']
      
      # for loop that iterates over the cities list
      for city in cities:
          print(city.title())

     

    • For 循环的组成部分

      1. 循环的第一行以关键字 for 开始,表示这是一个 for 循环

      2. 然后是 iteration_variable in iterable,表示正在被遍历的是可迭代的对象,并且用迭代变量表示当前正在被处理的可迭代对象的元素。在此示例中,迭代变量 city 在第一次迭代时将是“new york city”,在第二次迭代时将是“mountain view。

      3. for 循环头部始终以英文冒号 : 结束。

      4. for 循环头部之后的是在此 for 循环的每次迭代时运行的缩进代码块。在此块中,我们可以使用迭代变量访问当前正在被处理的元素的值。

        你可以随意命名迭代变量。常见模式是为迭代变量和可迭代对象指定相同的名称,但是分别使用单复数形式(例如 'city' 和 'cities)

    • 创建和修改列表

      • 除了从列表中提取信息之外,还可以使用 for 循环创建和修改列表。在 for 循环的每次迭代时向新列表中添加元素,创建一个列表。

        # Creating a new list
        cities = ['new york city', 'mountain view', 'chicago', 'los angeles']
        capitalized_cities = []
        ​
        for city in cities:
            capitalized_cities.append(city.title())

         

      • 修改列表稍微复杂些,需要使用新的函数:range()

        range() 是一个内置函数,用于创建不可变的数字序列。它有三个参数,必须都为整数。

        range(start=0, stop, step=1)

        Start是该序列的第一个数字,stop比该序列的最后一个数字大 1,step是该序列中每个数字之间的差。如果未指定的话,start默认为 0,step 默认为 1(即上述 =0和 =1)。

        • 如果你在 range() 的括号里指定一个参数,它将用作 'stop' 的值,另外两个参数使用默认值。 E.g. list(range(4)) 返回 [0, 1, 2, 3]

        • 如果你在 range() 的括号里指定两个参数,它们将用作 'start' 和 'stop' 的值,'step' 将使用默认值。 E.g. list(range(2, 6)) 返回 [2, 3, 4, 5]

        • 或者你可以为三个参数 'start、stop' 和 'step' 均指定一个值。 E.g. list(range(1, 10, 2)) 返回 [1, 3, 5, 7, 9]

  • While 循环

    • For 循环是一种“有限迭代”,意味着循环主体将运行预定义的次数。这与“无限迭代”循环不同,无限迭代循环是指循环重复未知次数,并在满足某个条件时结束,while 循环正是这种情况。

      card_deck = [4, 11, 8, 5, 13, 2, 8, 10]
      hand = []
      ​
      # adds the last element of the card_deck list to the hand list
      # until the values in hand add up to 17 or more
      while sum(hand)  <= 17:
          hand.append(card_deck.pop())

       

      这个示例包含两个函数。sum 返回列表中的元素之和,pop 是一个列表方法,它会从列表中删除最后一个元素并返回该元素。

    • While 循环的组成部分

      1. 第一行以关键字 while 开始,表示这是一个 while 循环。

      2. 然后是要检查的条件。在此示例中是 sum(hand) <= 17

      3. while 循环头部始终以冒号 : 结束。

      4. 该头部之后的缩进部分是 while 循环的主体。如果 while 循环的条件为 true,该循环的主体将被执行。每次运行循环主体时,条件将被重新评估。这个检查条件然后运行循环的流程将重复,直到该表达式变成 false。

  • Break 、 Contiune

    • 有时候我们需要更精准地控制何时循环应该结束,或者跳过某个迭代。在这些情况下,我们使用关键字 break 和 continue,这两个关键字可以用于 for和 while 循环。

      • break 使循环终止

      • continue 跳过循环的一次迭代

  • Zip 、 Enumerate

    • zip,zip 返回一个将多个可迭代对象组合成一个元组序列的迭代器。每个元组都包含所有可迭代对象中该位置的元素。

      list(zip(['a', 'b', 'c'], [1, 2, 3]))
      #output
      [('a', 1), ('b', 2), ('c', 3)]

       

    • Enumerateenumerate 是一个会返回元组迭代器的内置函数,这些元组包含列表的索引和值。当你需要在循环中获取可迭代对象的每个元素及其索引时,将经常用到该函数。

      letters = ['a', 'b', 'c', 'd', 'e']
      for i, letter in enumerate(letters):
          print(i, letter)
       #output
      0 a
      1 b
      2 c
      3 d
      4 e

       

  • 列表推导式

    • 在 Python 中,你可以使用列表推导式快速简练地创建列表。

      capitalized_cities = [city.title() for city in cities]

       

    • 借助列表推导式,我们可以使用 for 循环用一步创建一个列表。

      我们使用方括号 [] 创建列表推导式,括号里包含要对可迭代对象中的每个元素进行评估的条件。上述列表推导式对 cities 中的每个元素 city 调用 city.title(),以为新列表 capitalized_cities创建每个元素。

 

函数

定义函数

  • 函数定义示例

    def cylinder_volume(height, radius):
        pi = 3.14159
        return height * pi * radius ** 2

     

    调用该函数

    cylinder_volume(10, 3)

     

  • 函数定义包含几个重要部分。

    • 函数头部

      1. 函数头部始终以关键字 def 开始,表示这是函数定义。

      2. 然后是函数名称(在此例中是 cylinder_volume,因为函数名是要一个单词,所以需要用_进行连接),遵循的是和变量一样的命名规范。你可以在本页面下方回顾下命名规范。

      3. 名称之后是括号,其中可能包括用英文逗号分隔的参数(在此例中是 height 和 radius)。形参(或实参)是当函数被调用时作为输入传入的值,用在函数主体中。如果函数没有参数,这些括号留空。

      4. 头部始终以英文冒号 : 结束。

    • 函数主体

      • 函数的剩余部分包含在主题中,也就是函数完成操作的部分。

        1. 函数主体是在头部行之后缩进的代码。在此例中是定义 π 和返回体积的两行代码。

        2. 在此主体中,我们可以引用参数并定义新的变量,这些变量只能在这些缩进代码行内使用。

        3. 主体将经常包括 return 语句,用于当函数被调用时返回输出值。return 语句包括关键字 return,然后是经过评估以获得函数输出值的表达式。如果没有 return 语句,函数直接返回 None(例如内置 print() 函数)。

    • 函数命名规范

      • 函数名称遵守和变量一样的命名规范。

        1. 仅在函数名称中使用普通字母、数字和下划线。不能有空格,需要以字母或下划线开头。

        2. 不能使用在 Python 中具有重要作用的保留字或内置标识符,要了解 python 保留字列表,请参阅此处

        3. 尝试使用可以帮助读者了解函数作用的描述性名称。

默认参数

  • 我们可以向函数中添加默认参数,以便为在函数调用中未指定的参数提供默认值。

    def cylinder_volume(height, radius=5):
        pi = 3.14159
        return height * pi * radius ** 2

     

变量作用域

  • 函数变量域是指可以在程序的哪个部分引用或使用某个变量。

    在函数中使用变量时,务必要考虑作用域。如果变量是在函数内创建的,则只能在该函数内使用该变量。你无法从该函数外面访问该变量。

    # This will result in an error
    def some_function():
        word = "hello"
    ​
    print(word)

     

 

这意味着你可以为在不同函数内使用的不同变量使用相同的名称。

  # This works fine
  def some_function():
      word = "hello"
  
  def another_function():
      word = "goodbye"

 

 

像这样在函数之外定义的变量依然可以在函数内访问。

  # This works fine
  word = "hello"
  
  def some_function():
      print(word)
  
  print(word)

 

文档

  • 文档使代码更容易理解和使用。函数尤其容易理解,因为它们通常使用文档字符串,简称 docstrings。文档字符串是一种注释,用于解释函数的作用以及使用方式。下面是一个包含文档字符串的人口密度函数。

    def population_density(population, land_area):
        """Calculate the population density of an area. """
        return population / land_area

     

  • 文档字符串用三个引号引起来,第一行简要解释了函数的作用。如果你觉得信息已经足够了,可以在文档字符串中只提供这么多的信息;一行文档字符串完全可接受,如上述示例所示。

Lambda 表达式

  • 使用 Lambda 表达式创建匿名函数,即没有名称的函数。lambda 表达式非常适合快速创建在代码中以后不会用到的函数。尤其对高阶函数或将其他函数作为参数的函数来说,非常实用。

    我们可以使用 lambda 表达式将以下函数

    def multiply(x, y):
        return x * y

     

    简写为:

    double = lambda x, y: x * y

     

  • Lambda函数的组成部分

    1. 关键字 lambda 表示这是一个 lambda 表达式。

    2. lambda 之后是该匿名函数的一个或多个参数(用英文逗号分隔),然后是一个英文冒号 :。和函数相似,lambda 表达式中的参数名称是随意的。

    3. 最后一部分是被评估并在该函数中返回的表达式,和你可能会在函数中看到的 return 语句很像。

 

脚本编写

Anaconda安装教程 - 这个知乎帖子

配置Python编程环境

错误和异常

  • 当 Python 无法解析代码时,就会发生语法错误,因为我们没有遵守正确的 Python 语法。当出现拼写错误或第一次开始学习 Python 时,可能会遇到这些错误。

  • 当在程序执行期间出现意外情况时,就会发生异常,即使代码在语法上正确无误。Python 有不同类型的内置异常,可以在错误消息中查看系统抛出了什么异常。

处理错误

  • Try语句

    • 我们可以使用 try 语句处理异常。

      1. try:这是 try 语句中的唯一必需子句。该块中的代码是 Python 在 try 语句中首先运行的代码。

      2. except:如果 Python 在运行 try 块时遇到异常,它将跳到处理该异常的 except 块。

      3. else:如果 Python 在运行 try 块时没有遇到异常,它将在运行 try 块后运行该块中的代码。

      4. finally:在 Python 离开此 try 语句之前,在任何情形下它都将运行此 finally 块中的代码,即使要结束程序,例如:如果 Python 在运行 except 或 else 块中的代码时遇到错误,在停止程序之前,依然会执行此finally 块。

    • 我们实际上可以指定要在 except 块中处理哪个错误,如下所示:

      try:
          # some code
      except ValueError:
          # some code

       

      现在它会捕获 ValueError 异常,但是不会捕获其他异常。如果我们希望该处理程序处理多种异常,我们可以在 except 后面添加异常元组。

      try:
          # some code
      except (ValueError, KeyboardInterrupt):
          # some code

       

      或者,如果我们希望根据异常执行不同的代码块,可以添加多个 except 块。

      try:
          # some code
      except ValueError:
          # some code
      except KeyboardInterrupt:
          # some code

       

读写文件

  • 读取文件

    f = open('my_path/my_file.txt', 'r')
    file_data = f.read()
    f.close()

     

    1. 首先使用内置函数 open 打开文件。需要文件路径字符串。open 函数会返回文件对象,它是一个 Python 对象,Python 通过该对象与文件本身交互。在此示例中,我们将此对象赋值给变量 f

    2. 你可以在 open 函数中指定可选参数。参数之一是打开文件时采用的模式。在此示例中,我们使用 r,即只读模式。这实际上是模式参数的默认值。

    3. 使用 read 访问文件对象的内容。该 read 方法会接受文件中包含的文本并放入字符串中。在此示例中,我们将该方法返回的字符串赋值给变量 file_data

    4. 当我们处理完文件后,使用 close 方法释放该文件占用的系统资源。

  • 写入文件

    f = open('my_path/my_file.txt', 'w')
    f.write("Hello there!")
    f.close()

     

    1. 以写入 ('w') 模式打开文件。如果文件不存在,Python 将为你创建一个文件。如果以写入模式打开现有文件,该文件中之前包含的所有内容将被删除。如果你打算向现有文件添加内容,但是不删除其中的内容,可以使用附加 ('a') 模式,而不是写入模式。

    2. 使用 write 方法向文件中添加文本。

    3. 操作完毕后,关闭文件。

  • With

    • Python 提供了一个特殊的语法,该语法会在你使用完文件后自动关闭该文件。

      with open('my_path/my_file.txt', 'r') as f:
          file_data = f.read()

       

      该 with 关键字使你能够打开文件,对文件执行操作,并在缩进代码(在此示例中是读取文件)执行之后自动关闭文件。现在,我们不需要调用 f.close() 了!只能在此缩进块中访问文件对象 f。

导入本地脚本

  • 我们实际上可以导入其他脚本中的 Python,如果你处理的是大型项目,需要将代码整理成多个文件并重复利用这些文件中的代码,则导入脚本很有用。如果你要导入的 Python 脚本与当前脚本位于同一个目录下,只需输入 import,然后是文件名,无需扩展名 .py。

    import useful_functions

     

    • Import 语句写在 Python 脚本的顶部,每个导入语句各占一行。该 import 语句会创建一个模块对象,叫做 useful_functions。模块是包含定义和语句的 Python 文件。要访问导入模块中的对象,需要使用点记法。

    import useful_functions
    useful_functions.add_five([1, 2, 3, 4])

     

    • 我们可以为导入模块添加别名,以使用不同的名称引用它。

    import useful_functions as uf
    uf.add_five([1, 2, 3, 4])

     

  • 使用if main 块

    • 为了避免运行从其他脚本中作为模块导入的脚本中的可执行语句,将这些行包含在 if __name__ == "__main__" 块中。或者,将它们包含在函数 main() 中并在 if main 块中调用该函数。

      每当我们运行此类脚本时,Python 实际上会为所有模块设置一个特殊的内置变量 __name__。当我们运行脚本时,Python 会将此模块识别为主程序,并将此模块的 __name__ 变量设为字符串 "__main__"。对于该脚本中导入的任何模块,这个内置 __name__变量会设为该模块的名称。因此,条件 if __name__ == "__main__"会检查该模块是否为主程序。

      # useful_functions.py
      ​
      def mean(num_list):
          return sum(num_list) / len(num_list)
      ​
      def add_five(num_list):
          return [n + 5 for n in num_list]
      ​
      def main():
          print("Testing mean function")
          n_list = [34, 44, 23, 46, 12, 24]
          correct_mean = 30.5
          assert(mean(n_list) == correct_mean)
      ​
          print("Testing add_five function")
          correct_list = [39, 49, 28, 51, 17, 29]
          assert(add_five(n_list) == correct_list)
      ​
          print("All tests passed!")
      ​
      if __name__ == '__main__':
          main()

       

第三方库

  • 要使用 pip 安装软件包,在命令行中输入“pip install”,然后是软件包名称,如下所示:pip install package_name。该命令会下载并安装该软件包,以便导入你的程序中。安装完毕后,你可以使用从标准库中导入模块时用到的相同语法导入第三方软件包。

  • 实用的第三方软件包

    • IPython - 更好的交互式 Python 解释器

    • requests - 提供易于使用的方法来发出网络请求。适用于访问网络 API。

    • Flask - 一个小型框架,用于构建网络应用和 API。

    • Django - 一个功能更丰富的网络应用构建框架。Django 尤其适合设计复杂、内容丰富的网络应用。

    • Beautiful Soup - 用于解析 HTML 并从中提取信息。适合网页数据抽取。

    • pytest - 扩展了 Python 的内置断言,并且是最具单元性的模块。

    • PyYAML - 用于读写 YAML 文件。

    • NumPy - 用于使用 Python 进行科学计算的最基本软件包。它包含一个强大的 N 维数组对象和实用的线性代数功能等。

    • pandas - 包含高性能、数据结构和数据分析工具的库。尤其是,pandas 提供 dataframe!

    • matplotlib - 二维绘制库,会生成达到发布标准的高品质图片,并且采用各种硬拷贝格式和交互式环境。

    • ggplot - 另一种二维绘制库,基于 R's ggplot2 库。

    • Pillow - Python 图片库可以向你的 Python 解释器添加图片处理功能。

    • pyglet - 专门面向游戏开发的跨平台应用框架。

    • Pygame - 用于编写游戏的一系列 Python 模块。

    • pytz - Python 的世界时区定义。

  • 高效网络搜索方法

    • 在查询时,尝试使用 Python 或要使用的库的名称作为第一个字词。这样会告诉搜索引擎优先显示与你要使用的工具明确相关的结果。

    • 创建良好的搜索查询需要多次尝试。如果第一次尝试时没有找到有用的结果,再试一遍。

    • 尝试使用在一开始搜索时发现的网页上发现的关键字,使搜索引擎在后续搜索中转到更好的资源。

    • 复制粘贴错误消息作为搜索字词。这样会出现错误解释性信息和潜在原因。错误消息可能包括你所写的特定行号引用。只在搜索中包含这些信息之前的错误消息部分。

    • 如果找不到问题答案,自己提出问题!StackOverflow 等社区有一些行为规则,如果你要加入该社区,必须了解这些规则,但是别因为这些规则而不愿意使用这些资源。

  • 在线资源

    • Python 教程 - 这部分官方文档给出了 Python 的语法和标准库。它会举例讲解,并且采用的语言比主要文档的要浅显易懂。确保阅读该文档的 Python 3 版本!

    • Python 语言和库参考资料 - 语言参考资料和库参考资料比教程更具技术性,但肯定是可靠的信息来源。当你越来越熟悉 Python 时,应该更频繁地使用这些资源。

    • 第三方库文档 - 第三方库会在自己的网站上发布文档,通常发布于 https://readthedocs.org/。你可以根据文档质量判断第三方库的质量。如果开发者没有时间编写好的文档,很可能也没时间完善库。

    • 非常专业的网站和博客 - 前面的资源都是主要资源,他们是编写相应代码的同一作者编写的文档。主要资源是最可靠的资源。次要资源也是非常宝贵的资源。次要资源比较麻烦的是需要判断资源的可信度。Doug Hellmann 等作者和 Eli Bendersky 等开发者的网站很棒。不出名作者的博客可能很棒,也可能很糟糕。

    • StackOverflow - 这个问答网站有很多用户访问,因此很有可能有人之前提过相关的问题,并且有人回答了!但是,答案是大家自愿提供的,质量参差不齐。在将解决方案应用到你的程序中之前,始终先理解解决方案。如果答案只有一行,没有解释,则值得怀疑。你可以在此网站上查找关于你的问题的更多信息,或发现替代性搜索字词。

    • Bug 跟踪器 - 有时候,你可能会遇到非常罕见的问题或者非常新的问题,没有人在 StackOverflow 上提过。例如,你可能会在 GitHub 上的 bug 报告中找到关于你的错误的信息。这些 bug 报告很有用,但是你可能需要自己开展一些工程方面的研究,才能解决问题。

    • 随机网络论坛 - 有时候,搜索结果可能会生成一些自 2004 年左右就不再活跃的论坛。如果这些资源是唯一解决你的问题的资源,那么你应该重新思考下寻找解决方案的方式。

 

Numpy

Numpy 简介

  • NumPy 是 Numerical Python 的简称,它是 Python 中的科学计算基本软件包。NumPy 为 Python 提供了大量数学库,使我们能够高效地进行数字计算。

  • Numpy文档

  • Numpy 优势

    1. 速度快,在对大型数组执行操作时,NumPy 的速度比 Python 列表的速度快了好几百倍。这是因为 NumPy 数组本身能节省内存,并且 NumPy 在执行算术、统计和线性代数运算时采用了优化算法。

    2. NumPy 的另一个强大功能是具有可以表示向量和矩阵的多维数组数据结构。

    3. NumPy 具有的另一个强大优势是具有大量优化的内置数学函数。这些函数使你能够非常快速地进行各种复杂的数学计算,并且用到的代码很少(无需使用复杂的循环),使程序更容易读懂和理解。

      ....

  • 创建Numpy

    • NumPy 的核心是 ndarray,其中 nd 表示 n 维。ndarray 是一个多维数组,其中的所有元素类型都一样。换句话说,ndarray 是一个形状可以多样,并且可以存储数字或字符串的网格。

    • 我们可以使用 import 命令在 Python 中导入软件包。通常,我们使用 np 导入 NumPy。因此,你可以在 Jupyter notebook 中输入以下命令,导入 NumPy:

      import numpy as np
      # We import NumPy into Python
      import numpy as np
      ​
      # We create a 1D ndarray that contains only integers
      x = np.array([1, 2, 3, 4, 5])
      ​
      # Let's print the ndarray we just created using the print() command
      print('x = ', x)
      #output
      x = [1 2 3 4 5]

       

    NumPy 数据类型

  • 我们先创建一个具有指定形状的 ndarray,其中的元素全是 0。为此,我们可以使用 np.zeros() 函数。函数 np.zeros(shape) 会创建一个全是 0 并且为给定形状的 ndarray。因此,例如如果你想创建一个秩为 2 的数组,其中包含 3 行和 4 列,你将以 (行, 列) 的形式将该形状传递给函数,如以下示例所示:

    # We create a 3 x 4 ndarray full of zeros. 
    X = np.zeros((3,4))
    ​
    # We print X
    print()
    print('X = \n', X)
    print()
    ​
    # We print information about X
    print('X has dimensions:', X.shape)
    print('X is an object of type:', type(X))
    print('The elements in X are of type:', X.dtype)
    ​
    #output
    X =
    [[ 0. 0. 0. 0.]
     [ 0. 0. 0. 0.]
     [ 0. 0. 0. 0.]]
    ​
    X has dimensions: (3, 4)
    X is an object of type: class 'numpy.ndarray'
    The elements in X are of type: float64

     

  • ndayyay切片

    • 切片方式是在方括号里用冒号 : 分隔起始和结束索引。通常,你将遇到三种类型的切片:

      1. ndarray[start:end]
      2. ndarray[start:]
      3. ndarray[:end]

       

      第一种方法用于选择在 start 和 end 索引之间的元素。第二种方法用于选择从 start 索引开始直到最后一个索引的所有元素。第三种方法用于选择从第一个索引开始直到 end 索引的所有元素。请注意,在第一种方法和第三种方法中,结束索引不包括在内。此外注意,因为 ndarray 可以是多维数组,在进行切片时,通常需要为数组的每个维度指定一个切片。

 

Pandas

Pandas 简介

  • Pandas 是 Python 中的数据操纵和分析软件包。名称“Pandas”得名自计量经济学 Panel Data(面板数据)一词。Pandas 为 Python 带来了两个新的数据结构,即 Pandas Series 和 Pandas DataFrame。借助这两个数据结构,我们能够轻松直观地处理带标签数据和关系数据。

  • Pandas 文档

  • Pandas优势

    • 允许为行和列设定标签

    • 可以针对时间序列数据计算滚动统计学指标

    • 轻松地处理 NaN 值

    • 能够将不同格式的数据加载到 DataFrame 中

    • 可以将不同的数据集合并到一起

    • 与 NumPy 和 Matplotlib 集成

  • Pandas series 是一个像数组一样的一维对象,可以存储很多类型的数据,例如数字或字符串。Pandas Series 和 NumPy ndarray 之间的主要区别之一是你可以为 Pandas Series 中的每个元素分配索引标签。换句话说,你可以为 Pandas Series 索引指定任何名称。Pandas Series 和 NumPy ndarrays 之间的另一个明显区别是 Pandas Series 可以存储不同类型的数据。

    • 在 Python 中导入 Pandas。通常,我们使用 pd 导入 Pandas。因此,你可以在 Jupyter Notebook 中输入以下命令,导入 Pandas:

      import pandas as pd

       

  • 访问和删除 Pandas Series 中的元素

    • Pandas Series 提供了两个属性 .loc 和 .iloc,帮助我们清晰地表明指代哪种情况。属性 .loc 表示 位置,用于明确表明我们使用的是标签索引。同样,属性 .iloc 表示整型位置,用于明确表明我们使用的是数字索引。

    • 可以使用 .drop() 方法删除 Pandas Series 中的条目。Series.drop(label) 方法会从给定 Series 中删除给定的 label。请注意,Series.drop(label) 方法不在原地地从 Series 中删除元素,即不会更改被修改的原始 Series。

    • 我们可以通过在 .drop() 方法中将关键字 inplace设为 True,原地地从 Pandas Series 中删除条目。

  • 处理NaN

    • 同时使用了 .isnull() 和 sum() 方法来计算我们的 DataFrame 中的 NaN 值的数量。

    • .isnull() 方法返回一个大小和 store_items 一样的布尔型 DataFrame,并用 True表示具有 NaN 值的元素,用 False 表示非 NaN 值的元素。

    • 在 Pandas 中,逻辑值 True 的数字值是 1,逻辑值 False 的数字值是 0。因此,我们可以通过数逻辑值 True 的数量数出 NaN 值的数量。为了数逻辑值 True 的总数,我们使用 .sum() 方法两次。要使用该方法两次,是因为第一个 sum() 返回一个 Pandas Series,其中存储了列上的逻辑值 True 的总数。

    • 除了数 NaN 值的数量之外,我们还可以采用相反的方式,我们可以数非 NaN 值的数量。为此,我们可以使用 .count() 方法。

    • 从 DataFrame 中删除包含任何 NaN 值的行或列。如果 axis = 0.dropna(axis) 方法将删除包含 NaN 值的任何,如果 axis = 1.dropna(axis) 方法将删除包含 NaN 值的任何

    • 注意.dropna() 方法不在原地地删除具有 NaN 值的行或列。也就是说,原始 DataFrame 不会改变。你始终可以在 dropna() 方法中将关键字 inplace 设为 True,在原地删除目标行或列。

      如果我们不再删除 NaN 值,而是将它们替换为合适的值。例如,我们可以选择将所有 NaN 值替换为 0。为此,我们可以使用 .fillna() 方法。

将数据加载到Pandas DateFrame中

  • Pandas 使我们能够将不同格式的数据库加载到 DataFrame 中。用于存储数据库的最热门数据格式是 csv。CSV 是指逗号分隔值,是一种简单的数据存储格式。

    • 我们可以使用 pd.read_csv() 函数将 CSV 文件加载到 Pandas DataFrame 中。

    • 我们可以使用 .head() 方法查看前 5 行数据。

    • 还可以使用 .tail() 方法查看最后 5 行数据。

    • 还可以选择使用 .head(N) 或 .tail(N) 分别显示前 N 行和后 N 行数据。

    • 快速检查数据集中是否有任何 NaN 值。为此,我们将使用 .isnull() 方法,然后是 .any()方法,检查是否有任何列包含 NaN 值。

    • 在处理大型数据集时,通常有必要获取关于数据集的统计信息。通过使用 Pandas 的 .describe() 方法,可以获取关于 DataFrame 每列的描述性统计信息。

    • 另一个重要统计学衡量指标是数据相关性。数据相关性可以告诉我们不同列的数据是否有关联。我们可以使用 .corr() 方法获取不同列之间的关联性。

Project : 探索美国共享单车数据

data_analysis_projects

注:学习笔记是在优达学城学习时,参考部分课程内容总结而成。

Project : 探索美国共享单车数据-项目心得:
项目描述:用Python以及Pandas包、Numpy包等探索美国共享单车数据,编写一个接受原始输入并在终端中创建交互式体验的脚本。解决一些关于共享单车数据的问题。
项目心得:通过项目的完成,初步了解了共享单车云计算平台、单车用户数据、PaaS、等技术架构背景。熟悉了Python,Pandas、Numpy等包的使用,进一步加深数据分析流程认识。虽然在项目中遇到了很多问题,但最终通过查阅资料,不断地尝试下攻破了难关。让我明白了“bug不可怕,可怕的是不会去debug”,也让我对数据分析学习有了进一步的信心。

posted on 2018-10-21 22:38  python小白i  阅读(286)  评论(0)    收藏  举报

导航