当前位置:   article > 正文

Python数据分析与可视化(基础知识)

python数据分析与可视化

Python基础

本文首先介绍一下做数据分析与可视化所必备的Python基础,涉及Python的组合数据类型、控制流以及常用的内置函数。

数据类型

我们将讨论数据处理常见的数据类型。

  • Python中的列表
  • Python中的字典
  • Python中的集合

Python中的列表
列表是Python中常用的数据类型。列表中的元素是有序的,可变的,并且允许重复。我们可以用[]来创建一个列表。
同时我们还可以对一个列表进行分割也就是进行切片。切片意味着提取列表的一部分。切片的时候,第一个数字包含在返回集中,最后一个数字则不包含在返回集中。例如:

p1 = [1,2,3,4,5,6,7,8,9,10]
p2 = p1[0:5]
  • 1
  • 2

列表p2将为[1,2,3,4,5]。索引是从0开始的,第5个索引对应p1中的6但是返回的元素中不包括6
PS:也可以将p2 = p1[0:5]写为p2 = p1[:5].
以下代码是列表中常用的方法。请读者根据注释以及打印语句来理解每一行代码在做什么

# 创建一个列表
depths = [1, 5, 3, 6, 4, 7, 10, 12]

# 输出前5个元素。“:”之前没有数字就默认为0
first_5_depths = depths[:5]

print("---0---")
print(first_5_depths)

# 进行简单的求和操作
print("---1---")
print(sum(depths))

#求最大值
print("---2---")
print(max(depths))

# 末尾为负数,因此返回最后一个元素
print("---3---")
print(depths[-1])

# 返回列表倒数第二个元素到最后一个元素
# “:”没有数字表示到列表末尾
print("---4---")
print(depths[-2:])

#返回列表的第2,3,4个元素
# 记住是从0开始计数
print("---5---")
print(depths[2:5])

# 验证数字是否在列表中
print("---6---")
print(22 in depths)
print(1 in depths)

# 将另外一个元素添加到列表末尾
depths.append(44)
print("---7---")
print(depths)

# 将另外一个列表添加到列表中
depths.extend([100, 200])
print("---8---")
print(depths)

# 修改列表中的某个值
# 用100替换了列表中的第四个值
depths[4] = 100
print("---9---")
print(depths)

# 在列表某个位置插入元素
depths.insert(5, 1000)
print("---10---")
print(depths)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

Python中的字典
另外一个有用的数据类型是字典。字典包含键值对。也就是说,字典中的键是唯一的,并且每个键对应一个值。映射类型: 通过“键”-“值”的映射实现数据存储和查找。常规的字典是无序的,字典的键必须是不可变类型,如果键可变,就找不到对应存储的值了。我们可以用{}来初始化一个字典。让我们以代码展现某些功能。

# 初始化字典
# 首先是键,然后是":",最后是值
my_dict = {"age": 22, "birth_year": 1999, "name": "jack", "siblings": ["jill", "jen"]}

# 获取键为“age”的值
print("---0---")
print(my_dict['age'])

# 检查“age”在不在字典的键中
print("---1---")
print('age' in my_dict)

# 检查“company”在不在字典的键中
print("---2---")
print('company' in my_dict)

# 获取键为“age”的值
print("---3---")
print(my_dict.get('age'))

# 获取键为“company”的值
#如果不存在则返回-1
print("---4---")
print(my_dict.get('company', 1))

# 返回所有的键
print("---5---")
print(my_dict.keys())

# 返回所有的值
print("---6---")
print(my_dict.values())

# 返回所有键值对
print("---7---")
print(my_dict.items())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

我们还可以使用默认字典,这是一种更高级的字典,允许指定默认数据类型,请看代码

from collections import defaultdict  # 导入 defaultdict 类
my_default_dict = defaultdict(int)   # 生成默认字典
my_default_dict['age'] = 22          # 添加键值对
print(my_default_dict['company'])    # 打印键“company”所对应的值
  • 1
  • 2
  • 3
  • 4

在这个例子中我们用int数据类型来初始化defaultdic,这就意味着所有值都是整数,并且任何没有赋值的键的默认值都是0

Python中的集合
一系列互不相等元素的无序集合,重复会被自动删除,元素必须是不可变类型。集合可以进行并集,交集和差之类的运算。例如:

my_set = set()
my_set.add(1)
my_set.add(2)
my_set.add(1)
# 注意集合中只会保留一个1
print("---0---")
print(my_set)

my_set2 = set()
my_set2.add(1)
my_set2.add(2)
my_set2.add(3)
my_set2.add(4)
print("---1---")
print(my_set2)

# 输出交集
print("---1---")
print(my_set.intersection(my_set2))
print("---2---")

# 输出并集
print(my_set.union(my_set2))

# 打印差(在my_set中但是不在my_set2中)
print("---3---")
print(my_set.difference(my_set2))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

控制流和内置函数

本小节要介绍的内容

  • Python中的控制流
  • Python中的内置函数

Python中的控制流
if-else结构
If-then语句是任何编程语言的主要内容。基本上,如果某个条件,那么就会执行下面的语句。在Python中,elif代表else if,表示如果不满足先前的条件,请检查该条件。Else是所有剩余流量的全部条件。Python遵循以下语法:

if condition:
  statements
elif condition:
  statements
else:
  statements
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

以下是代码示例:

def age_check(age):

    if age > 40:  # 如果年龄大于40,则打印“年龄大于40”
        print("Older than 40")
    elif age > 30 and age <= 40: # 如果年龄大于30且小于等于40,则打印“30到40之间“
        print("Between 30 and 40")
    else:  # 如果以上条件都不满足,则打印”Other“
        print("Other")

print(age_check(41))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

for结构
循环可以迭代可迭代对象。这不是一个很有用的定义,因此让我们考虑最常见的用例列表。循环可以遍历列表或其他允许迭代的数据类型。
我们可以在enumerate()命令中添加迭代对象,以将计数器添加到循环中。如果您要遍历值列表同时仍可访问可迭代索引,则此功能很有用。

names = ['tyler', 'karen', 'jill']   # 列出包含的名字

for i, name in enumerate(names):     # 迭代名字
    print("Index: {0}".format(i))    # 打印数字索引
    print("Value: {0}".format(name)) # 打印索引对应的值
  • 1
  • 2
  • 3
  • 4
  • 5

说到列表和循环,有一种简单的方法可以在Python中将两者结合起来,称为列表推导。基本上,列表推导允许我们以压缩方式基于现有列表创建新列表。
这是一种通过列表表达式来创建大于5(最大14)的数字列表的方法
注意:range()创建一个值列表,该值从第一个数字开始,到最后一个数字之前的数字结束。
因此range(1,6)创建了[1,2,3,4,5]。
通过在末尾添加条件,我们可以将if语句添加到列表表达式中。看下面的实现:

numbers_gt_5 = [x for x in range(1,15) if x > 5]  # 循环迭代range并且只保留大于5的数
print(numbers_gt_5)
  • 1
  • 2

上面的程序在一个范围内循环

x for x in range(1,15)
  • 1

这意味着循环将迭代14次。并且在每次迭代中,都会执行一个if语句。如果x大于5,则if语句为true。因此,一旦迭代器x的值超过5,就将开始填充列表numbers_gt_5。

我们还可以将列表中的每个值加1,如下所示:

nums_plus_one = [x + 1 for x in range(5)]
print(nums_plus_one)
  • 1
  • 2

Python中的内置函数
sort函数
排序对列表来说很重要,但是排序很简单。

my_list = [2, 10, 1, -5, 22]
my_list.sort()  # 对列表进行排序

print(my_list)
  • 1
  • 2
  • 3
  • 4

sort()函数按最小值到最大值进行排序,如果想用更多的排序更能,那么建议使用sorted()函数。
这个函数可以使用reverse参数进行倒序排序,并使用key参数指定排序的基础。例如,我们不用常规排序,我们可以按如下所示的绝对值对进行倒序排序:

my_list = [2, 10, 1, -5, 22]

# 根据绝对值反向排序
my_list_sorted_abs = sorted(my_list, key=abs, reverse=True)

print(my_list_sorted_abs)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

zip函数
最后,一个稍微复杂的功能:zip。我们可以使用zip做很多有用的事情,但这是2个常见用例:

  • 将两个列表合并成一个元组列表
  • 将元组分为两个列表
    将两个列表合并成一个元组列表
    zip()实际上返回一个生成器,因此我们必须将其包装在list()中以进行打印。如果想遍历它,则不必这样做,因为生成器是可迭代的
list_1 = [1, 2, 3]  # 创建第一个列表
list_2 = ['x', 'y', 'z']  # 创建第二个列表

print(list(zip(list_1, list_2)))  #组合并打印
  • 1
  • 2
  • 3
  • 4

将元组分为两个列表
zip(*)函数可以将一个元组分为两个列表,与上述用例完全相反。

pairs = [('x', 1), ('y', 2), ('z', 3)]  # 元组集合
letters, numbers = zip(*pairs)  # 拆成两个列表

print(letters)  # 打印元组的第一个值
print(numbers)  #打印元组的第二个值
  • 1
  • 2
  • 3
  • 4
  • 5

现在,我们已经讨论了Python的基础知识,我们将探索我们的第一个外部Python库。

外部库Numpy

本节通过详细讨论numpy如何提供支持来处理单维或多维数组和不同功能的方法,引入了一个外部numpy库。
主要介绍如下内容:

  • 用Numpy处理数组
    一维数组
    二维数组

  • 重要功能
    计算点积
    产生随机值
    采样数据
    打乱顺序
    用Numpy处理数组
    一维数组
    为简单起见,我们可以将Numpy视为一种用于存储和操作数组类型的数据(类似于Python列表)进行存储和操作快速高效的库。 可以在此处找到有关Numpy的所有文档。 numpy数组在很多方面与标准Python列表有所不同。 值得注意的是,它们速度更快,占用空间更少,功能更多。 不过,请务必注意,这些数组的大小和类型是在创建时定义的固定大小。 不能像列表一样无限地附加新值。
    让我们来看看一些实际使用数组的方法。

import numpy as np

# 创建数组
np_array = np.array([5, 10, 15, 20, 25, 30])
print("--0--")

# 获取无重复的值
print(np.unique(np_array))
print("--1--")

# 计算标准差
print(np.std(np_array))
print("--2--")

# 计算最大值
print(np_array.max())
print("--3--")

# 将数组中的每个元素进行平方
print(np_array ** 2)
print("--4--")

# 将两个数组进行相加
print(np_array + np_array)
print("--5--")

# 将数组元平方再求和
print(np.sum(np_array ** 2))
print("--6--")

# 输出数组的形状
print(np_array.shape)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

二维数组
我们还将要了解如何使用二维数组,即同时具有行和列的数组。通常,这就是使用numpy表示矩阵的方式。

import numpy as np

# 创建二位数组
print("--0--")
np_2d_array = np.array([[1,2,3], 
                        [4,5,6]])
print(np_2d_array)

# 转置,即交换列和行
print("--1--")
np_2d_array_T = np_2d_array.T
print(np_2d_array_T)

# 打印数组形状(行数,列数)
print("--3--")
print(np_2d_array.shape)

# 通过索引获取二维数组元素
# 第一个索引是行数
# 第二个索引是列数
# 索引数字从0开始
print("--4--")
print(np_2d_array[1,1])
print(np_2d_array[0,2])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

重要功能
计算点积
numpy一个比较实用的功能是能够计算两个向量的点积。如果你需要复习什么点集,可以查看Wikipedia页面
代码如下:

import numpy as np
np_array = np.array([5, 10, 15, 20, 25, 30])
dot_product = np.dot(np_array, np_array)
print(dot_product)
  • 1
  • 2
  • 3
  • 4

产生随机值
Numpy具有出色的功能来帮助我们来产生随机值
首先,rand()函数返回一个随机数或0到1之间的一个数字。返回的随机值的数量取决于提供给该函数的形状。如果没有给出形状,则仅返回一个数字。

import numpy as np

# 产生[0,1)范围的一个随机数
print("--0--")
print(np.random.rand())

# 产生一个3行2列的随机矩阵,值在[0,1)范围内
print("--1--")
print(np.random.rand(3,2))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我们还可以使用randint()来生成从最小值(包含)返回到最大值(不含)的随机整数。我可以将最小值和最大值作为参数以及输出的大小传递给函数

import numpy as np

# Low=5, High=15, Size=2. 产生两个在[5,15)内的随机整数
print("--0--")
print(np.random.randint(5, 15, 2))

# Low=5, High=15, Size=(3,2).产生一个值在[5,15)范围内的3行2列的矩阵
print("--1--")
print(np.random.randint(5, 15, (3,2)))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

采样数据
有了数据,对其进行采样将会很有帮助
先复习一下什么是抽样,抽样是从总体中抽取较小群体的一种方法。例如,我们可以从中国人口中随机创建一个随机样本,在中国随机敲开10个门。样本量为10。

import numpy as np
array = np.array([1,2,3,4,5])

# 采样10个数据点并进行替换
print("--0--")
print(np.random.choice(array, 10, replace=True))

# 采样3个数据点并且不进行替换
print("--1--")
print(np.random.choice(array, 3, replace=False))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

打乱顺序
有时,随机地对数组进行排列会有所帮助。 Numpy有一个shuffle()函数可以做到这一点。

import numpy as np

x = [1,2,3,4,5]  # 创建一个数组
np.random.shuffle(x)  # 随机排序数组中的元素

print(x)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

seed( ) 用于指定随机数生成时所用算法开始的整数值,如果使用相同的seed( )值,则每次生成的随即数都相同,如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同。

for i in range(4):
    np.random.seed(5)
    print(np.random.rand(4))
  • 1
  • 2
  • 3

外部库Scipy

本节通过讨论scipy如何处理统计信息和概率功能来介绍scipy库
将涉及一下几个部分

  • 计算变量间的相关性
  • 从分布中生成样本
    正态分布
    概率密度
    累计分布
  • 计算统计信息

计算变量间的相关性
Scipy是一个进行科学计算的python库。Pandas基于Scipy库和Numpy库。在后文中我们再讲解Pandas,在此之前我们必须先要了解一下Scipy和Numpy。
相关性是两个变量之间统计关系的数值度量。这些变量通常是两列数据,例如,外界温度和下雨的可能性。
计算两个数据向量之间相关性的一种方法是使用Pearson相关性。此值的范围是-1和1。其中-1表示负相关,0表示没有关系,而1表示正相关。
注意:这些都指线性关系
在下图中,我们可以看到相关性的图形表示
在这里插入图片描述
比如人的身高和体重就是正相关的,因为一般高的人体重也比较重。再举一个负相关的列子,比如外面的气温和你家里加热器的使用频率,外面温度越高你使用加热器的频率就越低。而你穿的鞋子的码数和你的IQ则是没有关系的(显然两个完全不相关的)。
可以在维基百科中查找相关的数学公式。
下面是代码示例

from scipy import stats
import numpy as np

array_1 = np.array([1,2,3,4,5,6])  # 创建一个基于列表的数组
array_2 = array_1  # 创建一个具有同样值的数组

print(stats.pearsonr(array_1, array_2))  # 计算得到的相关性是一,因为他们的值一样。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

由于这两个数组的值是一样的,所以他们完全是正相关的。得到的结果是一个包含两个值的元组,第一个值代表相关性,而第二个值是p值(可以去了解一下Pearson相关性)。
从分布中生成样本
Scipy支持各种分布,我们首先来看一下正态分布。
正态分布
正态分布是围绕均值对称的分布,正态分布的值更接近均值。这是标准“钟形曲线”分布。见下图

在这里插入图片描述
如果你想从一个均值为0,标准偏差为10的正态分布中采样,你可以这样做:

from scipy import stats

x = stats.norm.rvs(loc=0, scale=10, size=10)  # 从一个均值为0,标准偏差为10的正态分布中生成10个样本

print(x)
  • 1
  • 2
  • 3
  • 4
  • 5

上面的代码使用loc参数接收平均值,使用scale参数接收标准偏差,使用size作为要返回的样本数。 如果采样了足够的数据点并绘制了结果图,则将看到以0为中心,标准偏差为10的正态分布。
概率密度
分布的另一种常见操作是计算概率密度。此功能可以计算采样来自某个分布的相对可能性。让我们看看。

from scipy import stats

p1 = stats.norm.pdf(x=-100, loc=0, scale=10)  # 获取-100来自均值为0,标准方差为10的正态分布的可能性
p2 = stats.norm.pdf(x=0, loc=0, scale=10)     # 获取0来自均值为0,标准方差为10的正态分布的可能性
print(p1)
print(p2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

从上面我们可以看到,相对于0值,从分布中得到-100(参数x)的可能性相对较小。 这是有道理的,因为我们的正态分布以0为中心,标准偏差为10。
累计分布
另一种常见的计算方法是累积分布,即采样值小于等于某个值x的概率。

from scipy import stats

p1 = stats.norm.cdf(x=0, loc=0, scale=10)  #计算采样值小于等于0的概率
print(p1)
  • 1
  • 2
  • 3
  • 4

我们可以看到x = 0的累积分布为0.5,因为0是平均值,而对于正态分布,一半的数据小于或等于平均值​​。
计算统计信息
最后,可以使用describe()函数为该数组计算多个描述性统计信息。代码如下:

from scipy import stats

print(stats.describe(stats.norm.rvs(loc=0, scale=1, size=500)))  # 为从均值为标准差为1的正态分布中获取的500个采样值计算统计信息。
  • 1
  • 2
  • 3

运行程序后可以获得数组的观测值数量,最小值,最大值,均值,方差,偏度和峰度。
注意:方差是标准偏差的平方。偏度是分布不对称的度量。峰度是对样本构成的分布是否突兀或平坦的。较大的值通常意味着存在更多异常值。


现在已经具备了基础知识,可以开始数据分析了,下节预告:数据读取。 由于本人能以有限,文中难免存在错误,还望各位批评指正。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/644231
推荐阅读
相关标签
  

闽ICP备14008679号