赞
踩
本文首先介绍一下做数据分析与可视化所必备的Python基础,涉及Python的组合数据类型、控制流以及常用的内置函数。
我们将讨论数据处理常见的数据类型。
Python中的列表
列表是Python中常用的数据类型。列表中的元素是有序的,可变的,并且允许重复。我们可以用[]来创建一个列表。
同时我们还可以对一个列表进行分割也就是进行切片。切片意味着提取列表的一部分。切片的时候,第一个数字包含在返回集中,最后一个数字则不包含在返回集中。例如:
p1 = [1,2,3,4,5,6,7,8,9,10]
p2 = p1[0:5]
列表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)
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())
我们还可以使用默认字典,这是一种更高级的字典,允许指定默认数据类型,请看代码
from collections import defaultdict # 导入 defaultdict 类
my_default_dict = defaultdict(int) # 生成默认字典
my_default_dict['age'] = 22 # 添加键值对
print(my_default_dict['company']) # 打印键“company”所对应的值
在这个例子中我们用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))
本小节要介绍的内容
Python中的控制流
if-else结构
If-then语句是任何编程语言的主要内容。基本上,如果某个条件,那么就会执行下面的语句。在Python中,elif代表else if,表示如果不满足先前的条件,请检查该条件。Else是所有剩余流量的全部条件。Python遵循以下语法:
if condition:
statements
elif condition:
statements
else:
statements
以下是代码示例:
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))
for结构
循环可以迭代可迭代对象。这不是一个很有用的定义,因此让我们考虑最常见的用例列表。循环可以遍历列表或其他允许迭代的数据类型。
我们可以在enumerate()命令中添加迭代对象,以将计数器添加到循环中。如果您要遍历值列表同时仍可访问可迭代索引,则此功能很有用。
names = ['tyler', 'karen', 'jill'] # 列出包含的名字
for i, name in enumerate(names): # 迭代名字
print("Index: {0}".format(i)) # 打印数字索引
print("Value: {0}".format(name)) # 打印索引对应的值
说到列表和循环,有一种简单的方法可以在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)
上面的程序在一个范围内循环
x for x in range(1,15)
这意味着循环将迭代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)
Python中的内置函数
sort函数
排序对列表来说很重要,但是排序很简单。
my_list = [2, 10, 1, -5, 22]
my_list.sort() # 对列表进行排序
print(my_list)
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)
zip函数
最后,一个稍微复杂的功能:zip。我们可以使用zip做很多有用的事情,但这是2个常见用例:
list_1 = [1, 2, 3] # 创建第一个列表
list_2 = ['x', 'y', 'z'] # 创建第二个列表
print(list(zip(list_1, list_2))) #组合并打印
将元组分为两个列表
zip(*)函数可以将一个元组分为两个列表,与上述用例完全相反。
pairs = [('x', 1), ('y', 2), ('z', 3)] # 元组集合
letters, numbers = zip(*pairs) # 拆成两个列表
print(letters) # 打印元组的第一个值
print(numbers) #打印元组的第二个值
现在,我们已经讨论了Python的基础知识,我们将探索我们的第一个外部Python库。
本节通过详细讨论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)
二维数组
我们还将要了解如何使用二维数组,即同时具有行和列的数组。通常,这就是使用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])
重要功能
计算点积
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)
产生随机值
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))
我们还可以使用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)))
采样数据
有了数据,对其进行采样将会很有帮助
先复习一下什么是抽样,抽样是从总体中抽取较小群体的一种方法。例如,我们可以从中国人口中随机创建一个随机样本,在中国随机敲开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))
打乱顺序
有时,随机地对数组进行排列会有所帮助。 Numpy有一个shuffle()函数可以做到这一点。
import numpy as np
x = [1,2,3,4,5] # 创建一个数组
np.random.shuffle(x) # 随机排序数组中的元素
print(x)
seed( ) 用于指定随机数生成时所用算法开始的整数值,如果使用相同的seed( )值,则每次生成的随即数都相同,如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同。
for i in range(4):
np.random.seed(5)
print(np.random.rand(4))
本节通过讨论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)) # 计算得到的相关性是一,因为他们的值一样。
由于这两个数组的值是一样的,所以他们完全是正相关的。得到的结果是一个包含两个值的元组,第一个值代表相关性,而第二个值是p值(可以去了解一下Pearson相关性)。
从分布中生成样本
Scipy支持各种分布,我们首先来看一下正态分布。
正态分布
正态分布是围绕均值对称的分布,正态分布的值更接近均值。这是标准“钟形曲线”分布。见下图
如果你想从一个均值为0,标准偏差为10的正态分布中采样,你可以这样做:
from scipy import stats
x = stats.norm.rvs(loc=0, scale=10, size=10) # 从一个均值为0,标准偏差为10的正态分布中生成10个样本
print(x)
上面的代码使用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)
从上面我们可以看到,相对于0值,从分布中得到-100(参数x)的可能性相对较小。 这是有道理的,因为我们的正态分布以0为中心,标准偏差为10。
累计分布
另一种常见的计算方法是累积分布,即采样值小于等于某个值x的概率。
from scipy import stats
p1 = stats.norm.cdf(x=0, loc=0, scale=10) #计算采样值小于等于0的概率
print(p1)
我们可以看到x = 0的累积分布为0.5,因为0是平均值,而对于正态分布,一半的数据小于或等于平均值。
计算统计信息
最后,可以使用describe()函数为该数组计算多个描述性统计信息。代码如下:
from scipy import stats
print(stats.describe(stats.norm.rvs(loc=0, scale=1, size=500))) # 为从均值为标准差为1的正态分布中获取的500个采样值计算统计信息。
运行程序后可以获得数组的观测值数量,最小值,最大值,均值,方差,偏度和峰度。
注意:方差是标准偏差的平方。偏度是分布不对称的度量。峰度是对样本构成的分布是否突兀或平坦的。较大的值通常意味着存在更多异常值。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。