本文来源公众号“萝卜大杂烩”,仅用于学术分享,侵权删,干货满满。
原文链接:长文预警,一篇文章扫盲Python、NumPy 和 Pandas,建议收藏慢慢看
Python作为简单易学的编程语言,想要入门还是比较容易的,接下来看看吧。
IDE 的选择
目前市面上流行着很多的 Python 编辑器,比如 Sublime,Notebook++ 等,不过还是推荐如下两个:
PyCharm:这是一个跨平台的 Python 开发工具,不但拥有常规的调试、语法高亮,智能提示等功能外,还自带多个数据库连接器,使你在调试数据库的时候也能得心应手,不再忙于到处下载各种数据库客户端。
Jupyter:这个是一个 web 式的在线编辑器,每次运行一行代码,你都可以立即得到结果,非常方便,在代码调试阶段,用处无限。
相信大家都有这种经验,学习任何一门语言时,入门的都是输出 Hello World,下面我们就来看看如何使用 Python 来输入 Hello World:
print("Hello World")
sum = 1 + 2
print("sum = %d" %sum)
>>>
Hello World
sum = 3
print 函数,用来在控制台打印输出,sum = 语法是声明变量并赋值,%d 是用来做字符串替换。
列表
list1 = ["1", "2", "test"]
print(list1)
list1.append("hello")
print(lists)
>>>
['1', '2', 'test']
['1', '2', 'test', 'hello']
list 是 Python 内置的一种数据类型,是一种有序的集合,可以随时添加和删除其中的元素。
元组
tuple1 = ("zhangsan", "lisi")
print(tuple1[0])
>>>
zhangsan
tuple 和 list 非常类似,但是 tuple 一旦初始化就不能修改.
字典
dict1 = {"name1": "zhangsan", "name2": "lisi", "name3": "wangwu"}
dict1["name1"]
>>>
'zhangsan'
Python 内置了字典:dict 全称 dictionary,在其他语言中也称为 map,使用键-值(key-value)存储,具有极快的查找速度。
集合
s = set([1, 2, 3])
print(s)
>>>
{1, 2, 3}
set 和 dict 类似,也是一组 key 的集合,但不存储 value。由于 key 不能重复,所以,在 set 中,没有重复的 key。
变量
变量的概念基本上和初中代数的方程变量是一致的,只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型。
a = 1
a = 3
print(a)
>>>
3
age = 30
if age >= 18:
print('your age is', age)
print('good')
else:
Print('your are not belong here')
>>>
your age is 30
good
if … else… 是非常经典的条件判断语句,if 后面接条件表达式,如果成立,则执行下面的语句,否则执行 else 后面的语句。同时还要注意,Python 语言是采用代码缩进的方式来判断代码块的,一般是四个空格或者一个 tab,两者不要混用。
names = {"zhangsan", "lisi", "wangwu"}
for name in names:
print(name)
>>>
lisi
zhangsan
wangwu
names 是一个集合,为可迭代对象,使用 for 循环,name 会依次被赋值给 names 中的元素值。
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
>>>
2500
在循环内部变量 n不断自减,直到变为-1时,不再满足 while 条件,循环退出。
切片
L = ['zhangsan', 'lisi', 'wangwu', 'zhaoliu']
print(L[1])
print(L[1:3])
>>>
lisi
['lisi', 'wangwu']
Python 中,下标都是从 0 开始的,且都是左闭右开区间
迭代
对于列表、元组和字典,都是可迭代对象,可以使用 for 来进行迭代取值
L = ['zhangsan', 'lisi', 'wangwu', 'zhaoliu']
D = {"zhangsan":1, "lisi": 2, "wangwu": 3, "zhaoliu": 4}
for l in L:
print(l)
print('\n')
for k,v in D.items():
print("键:", k, ",", "值", v)
>>>
zhangsan
lisi
wangwu
zhaoliu键: zhangsan , 值 1
键: lisi , 值 2
键: wangwu , 值 3
键: zhaoliu , 值 4
对于字典,使用 items(),可是同时遍历键值对
调用函数
Python 内置了很多有用的函数,我们可以直接调用。
>>> abs(100)
100
>>> abs(-20)
20
>>> abs(12.34)
12.34
>>> max(1, 2)
2
>>> max(2, 3, 1, -5)
3
在调用函数时,如果传入的参数有问题,程序会抛出异常。 这里包含了 Python 中所有的内置函数: 内置函数 — Python 3.12.1 文档
定义函数
在 Python 中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
def add(num1, num2):
return num1 + num2result = add(1,2)
print(result)
>>>
3
在代码中,定义了一个叫做 add 的函数,它会接收两个参数,并且会返回他们之和。函数定义之后,可以使用函数名称后面跟()来调用,如果函数有返回值,可以赋给一个变量来接收。
1.7 模块
调用模块
Python 本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。
import time
def sayTime():
now = time.time()
return nownowtime = sayTime()
print(nowtime)
>>>
1566550687.642805
使用 import 来导入模块,之后就可以调用该模块为我们提供的各种方法变量等。
模块说白了就是一组工具的集合,我们当然可以自己编写一些工具,然后组成自己的模块,供后面编程使用。
我们自己编写模块,一般目录结构如下
mytest ├─ __init__.py ├─ test1.py └─ test2.py
现在我们就可以在其他的文件中引用并调用这两个 test 工具文件了
import mytest mytest.test1
你应该注意到了 __init__.py
文件,这个文件可以是空文件,包含了 __init__.py
文件的文件夹就是一个”包“(Package)。如果我们需要像上面那样引用文件,就必须包含 __init__.py
文件。
安装第三方模块
在 Python 中,安装第三方模块,是通过包管理工具 pip 完成的。
一般来说,第三方库都会在 Python 官方的pypi.python.org网站注册,要安装一个第三方库,必须先知道该库的名称,可以在官网或者 pypi 上搜索,比如 Pillow 的名称叫Pillow,因此,安装 Pillow 的命令就是:
pip install Pillow
类和实例
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如 Student 类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
在 Python 中,使用 class 关键字来定义类
class Student(object): pass
定义好类之后,就可以实例化该类了
zhangsan = Student()
zhangsan.age = 20
print(Student)
print(zhangsan)
print(zhangsan.age)
>>>
<__main__.Student object at 0x00EA7350>
20
此时,变量 zhangsan 就是类 Student 的一个实例了。同时我们还给 zhangsan 绑定了一个属性 age 并赋值。
请谨记面向对象三大基本要素:抽象,封装,继承。如果你当前对这些还没有太多的概念的话,也不要紧,你可以在后面的学习中慢慢体会。
读取文件,是后面要经常用到的操作,在 Python 中,使用 open 函数可以非常方便的打开一个文件
f = open('/Users/tanxin/test.txt', 'r')
f.read()
f.close()
标示符 'r' 表示读,这样,我们就成功地打开了一个文件,然后使用 read 函数来读取文件内容,最后用 close 来关闭文件。 文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的
使用 with 来方便的打开文件
with open('/Users/tanxin/test.txt', 'r') as f:
print(f.read())
with 语句帮助我们完成了 close 的过程
文件读取还有 readline() 和 readlins() 两个函数。readline() 一次读取一行数据,readlines() 一次读取所有内容并按行返回一个列表。
正则表达式是一个很大的学科,其中的内容是完全可以单独写满一本书的,我们这里只做些简单的介绍。
Python 中提供了 re 模块来做正则
import re
str1 = "010-56765"
res = re.match(r'(\d{3})-(\d{5})', str1)
print(res)
print(res.group(0))
print(res.group(1))
print(res.group(2))
>>>
010-56765
010
56765
match() 方法判断是否匹配,如果匹配成功,返回一个 Match 对象,否则返回 None 配合 group 方法,可以有效的提取出字字符串。
NumPy 不仅仅是 Python 科学计算中使用最多的库,还是 SciPy,Pandas 等库的基础,它提供了更加高级有效的数据结构,是专门为科学计算而生的库。
NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用, 这种组合广泛用于替代 MatLab,是一个强大的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。
NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
ndarray 内部组成
一个指向数据(内存或内存映射文件中的一块数据)的指针
数据类型或 dtype,描述在数组中固定大小值的格子
一个表示数组形状(shape)的元组,表示各维度大小的元组
一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要”跨过“的字节数
创建一个 ndarray 只需要调用 NumPy 的 array 函数即可:
import numpy as np
a = np.array([1, 2, 2])
b = np.array([[1, 2], [5, 5], [7, 8]])
b[1,1]=10
print(a.shape)
print(b.shape)
print(a.dtype)
print(b)
>>>
(3,)
(3, 2)
int32
[[ 1 2]
[ 5 10]
[ 7 8]]
引用 numpy 库,调用 array 函数即可创建 ndarray。 创建一维数组只需要传入一个 list,创建多维数组,需要先把一个数组作为一个元素嵌套起来,再放入另一个数组当中。 提取 array 中的元素,可以使用切片的操作,b[1,1]。 使用 shape 属性来获取数组的形状(大小),如 b 数组为一个三行两列的数组。 使用 dtype 属性来获取数组中的数据类型。
NumPy 支持的数据类型比 Python 内置的类型要多,下面罗列了一些常见类型
名称 | 描述 |
---|---|
bool_ | 布尔型数据类型(True 或者 False) |
int_ | 默认的整数类型 |
int32 | 整数(-2147483648 to 2147483647) |
uint32 | 无符号整数(0 to 4294967295) |
float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
数据类型对象(dtype)
数据类型对象可以用来创建符合我们期望数据结构的数组
numpy.dtype(object, align, copy)
object:要转换的数据类型对象
align:如果为 True,填充字段使其类似 C 的结构体
copy:复制 dtype 对象,如果为 False,则是对内置数据类型对象的引用
使用 dtype 创建结构数组
mydtype = np.dtype({
'names': ['name', 'age', 'sex'],
'formats': ['S32', 'i4', 'S32']
})
persons = np.array([
('zhangsan', 20, 'man'),
('lisi', 18, 'woman'),
('wangwu', 30, 'man')
],
dtype=mydtype)
print(persons)
>>>
[(b'zhangsan', 20, b'man') (b'lisi', 18, b'woman') (b'wangwu', 30, b'man')]
首先通过 dtype 函数定义一个结构类型,然后再使用 array 函数构建数组,dtype 参数使用我们定义的即可。
NumPy 数组的维数称为秩(rank),一维数组的秩为 1,二维数组的秩为 2,以此类推。
在 NumPy 中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。
很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。
下面罗列了比较重要的 ndarray 对象属性
属性 | 说明 |
---|---|
ndim | 秩,即轴的数量或维度的数量 |
shape | 数组的维度 |
size | 数组元素的总个数 |
dtype | 元素的类型 |
itemsize | 每个元素的大小,以字节为单位 |
空数组
x = np.empty([3,2], dtype=int)
print(x)
>>>
[[0 0]
[0 0]
[0 0]]
numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组
0 数组
zero1 = np.zeros(5)
zero2 = np.zeros(4, dtype=int)
print(zero1)
print(zero2)
>>>
[0. 0. 0. 0. 0.]
[0 0 0 0]
1 数组
one1 = np.ones(3)
one2 = np.ones(4, dtype=float)
print(one1)
print(one2)
>>>
[1. 1. 1.]
[1. 1. 1. 1.]
从已有数组创建数组
numpy.asarray,从列表,元组,多维数组创建数组
list1 = [1, 3, 5]
tuple1 = (1, 2, 3)
one = np.ones((2,3), dtype=int)
array1 = np.asarray(list1)
array2 = np.asarray(tuple1)
array3 = np.asarray(one)
print(array1)
print(array2)
print(array3)
>>>
[1 3 5]
[1 2 3]
[[1 1 1]
[1 1 1]]
numpy.frombuffer,以流的形式读入转化成数组
str1 = b"Hello world"
buffer1 = np.frombuffer(str1, dtype='S1')
print(buffer1)
>>>
[b'H' b'e' b'l' b'l' b'o' b' ' b'w' b'o' b'r' b'l' b'd']
numpy.fromiter,可以从可迭代对象中建立数组
range1 = range(5)
iter1 = np.fromiter(range1, dtype=int)
print(iter1)
>>>
[0 1 2 3 4]
numpy.arange,从数值范围创建数组
myarray1 = np.arange(5)
print(myarray1)
>>>
[0 1 2 3 4]
numpy.linspace,建立一个等差数列的数组
myarray2 = np.linspace(1,9,5)
print(myarray2)
>>>
[1. 3. 5. 7. 9.]
切片和索引
ndarray 对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。
ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
a = np.arange(10)
print(a)
s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s])
>>>
[0 1 2 3 4 5 6 7 8 9]
[2 4 6]
也可以使用冒号(:)来做切片
a = np.arange(10)
print(a)
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
print(b)
>>>
[0 1 2 3 4 5 6 7 8 9]
[2 4 6]
修改数组形状
nunpy.reshape,可以在不改变数据的条件下修改数组形状
a = np.arange(6)
print("原始数组:", a)
b = a.reshape(3, 2)
print("变换后数组:", b)
>>>
原始数组: [0 1 2 3 4 5]
变换后数组: [[0 1]
[2 3]
[4 5]]
numpy.ndarray.flat,是一个数组元素迭代器,可以依次处理每个元素
a = np.arange(9).reshape(3,3)
print ('原始数组:')
for row in a:
print (row)
#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
print ('迭代后的数组:')
for element in a.flat:
print (element)
>>>
原始数组:
[0 1 2]
[3 4 5]
[6 7 8]
迭代后的数组:
0
1
2
3
4
5
6
7
8
翻转数组
numpy.transpose,可以对换数组的维度
a = np.arange(10).reshape(2, 5)
print(a)
b = a.transpose()
print(b)
>>>
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0 5]
[1 6]
[2 7]
[3 8]
[4 9]]
连接数组
numpy.concatenate,用于连接相同形状的两个或多个数组
a = np.array([[1,2],[3,4]])
print ('第一个数组:')
print (a)b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)# 两个数组的维度相同
print ('沿轴 0 连接两个数组:')
print (np.concatenate((a,b)))
print ('沿轴 1 连接两个数组:')
print (np.concatenate((a,b),axis = 1))
>>>
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
沿轴 0 连接两个数组:
[[1 2]
[3 4]
[5 6]
[7 8]]
沿轴 1 连接两个数组:
[[1 2 5 6]
[3 4 7 8]]
分割数组
numpy.split,可以将数组分割为子数组
a = np.arange(9)
print ('第一个数组:')
print (a)
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)
>>>
第一个数组:
[0 1 2 3 4 5 6 7 8]将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]将数组在一维数组中表明的位置分割:
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
另外还有对于数组元素的添加与删除操作
函数 | 描述 |
---|---|
resize | 返回指定形式的新数组 |
append | 将值添加到数组末尾 |
insert | 延指定轴将数值插入到指定下标之前 |
delete | 删掉某个轴的子数组,返回删除后的新数组 |
unique | 查找数组内的唯一元素 |
计算最大最小值
numpy.amin(),计算数组中延指定轴的最小值
numpy.amax(),计算数组中延指定轴的最大值
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print ('数组是:')
print (a)
print ('调用 amin() 函数:')
print (np.amin(a,1))
print ('再次调用 amin() 函数:')
print (np.amin(a,0))
print ('调用 amax() 函数:')
print (np.amax(a))
print ('再次调用 amax() 函数:')
print (np.amax(a, axis = 0))
>>>
数组是:
[[3 7 5]
[8 4 3]
[2 4 9]]
调用 amin() 函数:
[3 3 2]
再次调用 amin() 函数:
[2 4 3]
调用 amax() 函数:
9
再次调用 amax() 函数:
[8 7 9]
不指定 axis 时,会在整个数组中查找最大或最小。 axis = 0,是对每一列进行操作,即把数组看成 [3, 8, 2],[7, 4, 4],[5, 3, 9],从中选出最大或最小 axis = 1,是对每一行进行操作,即把数组看成 [3, 7, 5],[8, 4, 3],[2, 4, 9]。
这里的 axis 不是很容易理解,还希望你能在这里多花费些时间,去实践,去领悟。
numpy.ptp,可以计算数组元素中最大值与最小值之差
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print ('我们的数组是:')
print (a)
print ('调用 ptp() 函数:')
print (np.ptp(a))
print ('沿轴 1 调用 ptp() 函数:')
print (np.ptp(a, axis = 1))
print ('沿轴 0 调用 ptp() 函数:')
print (np.ptp(a, axis = 0))
>>>
我们的数组是:
[[3 7 5]
[8 4 3]
[2 4 9]]
调用 ptp() 函数:
7
沿轴 1 调用 ptp() 函数:
[4 5 7]
沿轴 0 调用 ptp() 函数:
[6 3 6]
numpy.percentile,计算百分位数,表示小于这个值的观察值的百分比
理解百分位数:第 p 个百分位数表示,它使得至少有 p% 的数据项小于等于这个值,且至少有 (100 - p)% 的数据项大于等于这个值。
例如:某个同学语文考试分数为 80,如果这个分数正好位于所有学生成绩的第 80 百分位数,那么即可知该成绩大于约 80% 人,约 20% 人的成绩高于该同学。
a = np.array([[10, 7, 4], [3, 2, 1]])
print ('数组是:')
print (a)
print ('调用 percentile() 函数:')
# 50% 的分位数,就是 a 里排序之后的中位数
print (np.percentile(a, 50))
# axis 为 0,在纵列上求
print (np.percentile(a, 50, axis=0))
# axis 为 1,在横行上求
print (np.percentile(a, 50, axis=1))
# 保持维度不变
print (np.percentile(a, 50, axis=1, keepdims=True))
>>>
数组是:
[[10 7 4]
[ 3 2 1]]
调用 percentile() 函数:
3.5
[6.5 4.5 2.5]
[7. 2.]
[[7.]
[2.]]
numpy.median,计算数组元素的中位数
a = np.array([[10, 7, 4], [3, 2, 1]])
print ('数组是:')
print (a)
print(np.median(a))
>>>
3.5
可以看出,percentile 中 p 等于 50 时,就是中位数
numpy.mean,平均数
a = np.array([[10, 7, 4], [3, 2, 1]])
print ('数组是:')
print (a)
print(np.mean(a))
>>>
4.5
numpy.average,计算加权平均值
a = np.array([1,2,3,4])
print ('数组是:')
print (a)
print ('调用 average() 函数:')
print (np.average(a))
wts = np.array([4,3,2,1])
print ('再次调用 average() 函数:')
print (np.average(a,weights = wts))
>>>
数组是:
[1 2 3 4]
调用 average() 函数:
2.5
再次调用 average() 函数:
2.0
标准差和方差
标准差是一组数据平均值分散程度的一种度量,是方差的算术平方根。
方差是每个样本值与全体样本值的平均数之差的平方值的平均数。
print (np.std([1,2,3,4]))
print (np.var([1,2,3,4]))
>>>
1.118033988749895
1.25
在 numpy 中排序一行代码就可以完成,直接调用 sort 函数即可。
numpy.sort(a, axis, kind, order)
默认情况下,使用的是快速排序算法;在 kind 里,可以指定 quicksort、mergesort 和 heapsort,分别表示快速排序、合并排序和堆排序;axis 默认是 -1,沿着最后的轴排序, axis=0 按列排序,axis=1 按行排序;对于 order 字段,如果数值包含字段,可以填写要排序的字段。
a = np.array([[3,7],[9,1]])
print ('数组是:')
print (a)
print ('调用 sort() 函数:')
print (np.sort(a))
print ('按列排序:')
print (np.sort(a, axis = 0))
print ('按行排序:')
print (np.sort(a, axis = 1))
>>>
数组是:
[[3 7]
[9 1]]
调用 sort() 函数:
[[3 7]
[1 9]]
按列排序:
[[3 1]
[9 7]]
按行排序:
[[3 7]
[1 9]]
在数据分析当中,我们通常使用 Pandas 来做数据清理的工作。在真实的工作生活中,我们拿到的数据往往都是不整洁的,空值、重复值、无效值等等信息都会干扰我们的分析,此时我们就需要按部就班的完成数据的清理。数据清理是数据分析中非常重要的一步,也是非常繁琐的一步,当然,在你掌握了 Pandas 库之后,你就好像是得到了一把削铁如泥的宝剑,数据清理工作的效率会大大提高。
Pandas 主要有两种数据结构,分别是 Series 和 DataFrame,他们分别表示一维的序列和二维的表结构。
维数 | 名称 | 描述 |
---|---|---|
1 | Series | 可以看做有标签(默认是整数序列 RangeIndex;可以重复)的一维数组(同类型)。是 scalars(标量) 的集合,同时也是 DataFrame 的元素。 |
2 | DataFrame | 一般是二维标签,尺寸可变的表格结构,具有潜在的异质型列。 |
Series 是一个定长的字典序列。它相当于是两个 ndarray,一个代表 index,一个代表 values。
import pandas as pd
s = pd.Series(data, index=index)
此处的 data,可以是如下的数据类型:
Python 中的 dict
一个 ndarray
一个标量,比如:4
而 index 的默认值是 0,1,2… 递增的整数序列。
指定 index
s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
print(s)
>>>
a -0.595567
b -0.201314
c 1.516812
d 0.102395
e -1.009924
dtype: float64
不指定 index
s1 = pd.Series(['a', 'b', 'c', 'd'])
print(s1)
>>>
0 a
1 b
2 c
3 d
dtype: object
通过字典来创建 Series
d= {'a': 1, 'b': 2, 'c': 3}
s2 = pd.Series(d)
print(s2)
>>>
a 1
b 2
c 3
dtype: int64
DataFrame 是一个二维的数据结构,可以把它理解为数据表格或者是 SQL 表,或者是由 Series 对象组成的字典。
d = {"Chinese": [80, 85, 90], "Math": [85, 70, 95], "English": [90, 95, 90]}
df1 = pd.DataFrame(d)
print(df1)
df2 = pd.DataFrame(d, index=['zhangsan', 'lisi', 'wangwu'])
print(df2)
print(df2.columns, df2.index)
>>>
Chinese Math English
0 80 85 90
1 85 70 95
2 90 95 90
Chinese Math English
zhangsan 80 85 90
lisi 85 70 95
wangwu 90 95 90
Index(['Chinese', 'Math', 'English'], dtype='object') Index(['zhangsan', 'lisi', 'wangwu'], dtype='object')
通过 index 选择 DataFrame 中的数据
操作 | 语法 | 结果类型 |
---|---|---|
选择某一列 | df[col] | Series |
通过标签选择某一行 | df.loc[label] | Series |
通过标签位置选择某一行 | df.iloc[loc] | Series |
切片获取某些行 | df[5:10] | DataFrame |
通过布尔向量获取某些行 | df[bool_vec] | DataFrame |
代码
print(df2['Chinese'], '\n')
print(df2.loc['zhangsan'], '\n')
print(df2.iloc[-1], '\n')
print(df2[0:2], '\n')
print(df2[df2>85], '\n')
>>>
zhangsan 80
lisi 85
wangwu 90
Name: Chinese, dtype: int64 Chinese 80
Math 85
English 90
Name: zhangsan, dtype: int64 Chinese 90
Math 95
English 90
Name: wangwu, dtype: int64 Chinese Math English
zhangsan 80 85 90
lisi 85 70 95 Chinese Math English
zhangsan NaN NaN 90
lisi NaN NaN 95
wangwu 90.0 95.0 90
df = pd.read_csv("test.csv")
print(df.head())
print('\n')
print(type(df))
>>>
name age score
0 zhangsan 30.0 80.0
1 lisi 20.0 NaN
2 wangwu 25.0 100000.0
3 zhaoliu NaN 32.0
4 maqi 33.0 60.0
df.to_csv('my.csv') df.to_excel('my.xlsx')
print(df.index, '\n')
print(df.columns, '\n')
print(df.to_numpy(), '\n')
print(df.describe())
>>>
RangeIndex(start=0, stop=5, step=1) Index(['name', 'age', 'score'], dtype='object') [['zhangsan' 30.0 80.0]
['lisi' 20.0 nan]
['wangwu' 25.0 100000.0]
['zhaoliu' nan 32.0]
['maqi' 33.0 60.0]] age score
count 4.000000 4.000000
mean 27.000000 25043.000000
std 5.715476 49971.337211
min 20.000000 32.000000
25% 23.750000 53.000000
50% 27.500000 70.000000
75% 30.750000 25060.000000
max 33.000000 100000.000000
describe 是非常常用的函数,可以通过它来在整体上查看数据的全貌,有助于了解数据。
按轴排序
print(df.sort_index(axis=1, ascending=False))
>>>
score name age
0 80.0 zhangsan 30.0
1 NaN lisi 20.0
2 100000.0 wangwu 25.0
3 32.0 zhaoliu NaN
4 60.0 maqi 33.0
按数值排序
print(df.sort_values(by='score'))
>>>
name age score
3 zhaoliu NaN 32.0
4 maqi 33.0 60.0
0 zhangsan 30.0 80.0
2 wangwu 25.0 100000.0
1 lisi 20.0 NaN
查看缺失值
print(df.isnull(),'\n')
print(df.isnull().any())
>>>
name age score
0 False False False
1 False False True
2 False False False
3 False True False
4 False False False name False
age True
score True
dtype: bool
可以方便的看出数据中,哪些列是存在空值的。
删除/填充空值
df1 = df.copy()
print(df1, '\n')
print(df1.dropna(how='any'), '\n')
print(df1.fillna(value=50))
>>>
name age score
0 zhangsan 30.0 80.0
1 lisi 20.0 NaN
2 wangwu 25.0 100000.0
3 zhaoliu NaN 32.0
4 maqi 33.0 60.0 name age score
0 zhangsan 30.0 80.0
2 wangwu 25.0 100000.0
4 maqi 33.0 60.0 name age score
0 zhangsan 30.0 80.0
1 lisi 20.0 50.0
2 wangwu 25.0 100000.0
3 zhaoliu 50.0 32.0
4 maqi 33.0 60.0
df1.rename(columns={'name': 'student'}, inplace = True)
print(df1)
>>>
student age score
0 zhangsan 30.0 80.0
1 lisi 20.0 NaN
2 wangwu 25.0 100000.0
3 zhaoliu NaN 32.0
4 maqi 33.0 60.0
df1 = df1.drop(columns=['age'])
print(df1, '\n')
df1 = df1.drop(index=[1])
print(df1)
>>>
student score
0 zhangsan 80.0
1 lisi NaN
2 wangwu 100000.0
3 zhaoliu 32.0
4 maqi 60.0 student score
0 zhangsan 80.0
2 wangwu 100000.0
3 zhaoliu 32.0
4 maqi 60.0
df = df.drop_duplicates() # 去除重复行
df1['score'].astype('str')
apply 函数的应用 apply 用来将函数应用到数据上。
df2 = df1['score'].apply(lambda x: x * 2)
print(df2)
>>>
0 160.0
2 200000.0
3 64.0
4 120.0
Name: score, dtype: float64
以上代码等价于
list(map(lambda x: x*2, df1['score'])) >>> [160.0, 200000.0, 64.0, 120.0]
由此可以看出,apply 是一个高效且简洁的函数,可以快速把函数作用到每个元素之上。
所谓的直方图化,就是函数 value_counts,该函数可以查看数据中,每列中有多少不同值,且各个不同值出现的次数
print(df, '\n')
df3 = df.fillna(60)
df3.loc[5] = ['qianba', 20, 80] # 新增一行
print(df3['score'].value_counts())
>>>
name age score
0 zhangsan 30.0 80.0
1 lisi 20.0 NaN
2 wangwu 25.0 100000.0
3 zhaoliu NaN 32.0
4 maqi 33.0 60.0 60.0 2
80.0 2
32.0 1
100000.0 1
Name: score, dtype: int64
合并
1、使用 concat 连接两个 Pandas 对象
print(df3, '\n')
df4 = df3.copy()
df3 = pd.concat([df3, df4], ignore_index=True)
print(df3)
>>>
name age score
0 zhangsan 30.0 80.0
1 lisi 20.0 60.0
2 wangwu 25.0 100000.0
3 zhaoliu 60.0 32.0
4 maqi 33.0 60.0
5 qianba 20.0 80.0 name age score
0 zhangsan 30.0 80.0
1 lisi 20.0 60.0
2 wangwu 25.0 100000.0
3 zhaoliu 60.0 32.0
4 maqi 33.0 60.0
5 qianba 20.0 80.0
6 zhangsan 30.0 80.0
7 lisi 20.0 60.0
8 wangwu 25.0 100000.0
9 zhaoliu 60.0 32.0
10 maqi 33.0 60.0
11 qianba 20.0 80.0
2、使用 merge 函数
基于某一列进行连接
left = pd.DataFrame({'key': ['foo', 'bar', 'loo'], 'lval': [1, 2, 3]})
right = pd.DataFrame({'key': ['foo', 'bar', 'roo'], 'rval': [3, 4, 5]})
print(left, '\n')
print(right, '\n')
print(pd.merge(left, right, on='key'))
>>>
key lval
0 foo 1
1 bar 2
2 loo 3
key rval
0 foo 3
1 bar 4
2 roo 5
key lval rval
0 foo 1 3
1 bar 2 4
内连接(innert),取键的交集
print(pd.merge(left, right, how='inner'))
>>>
key lval rval
0 foo 1 3
1 bar 2 4
还有左连接、右连接和外连接,你可以自己尝试下,看看有什么区别。
分组
所谓的分组,就是根据一些标准,将数据分解成一些组,将函数独立的应用到每个组上,最后将结果组合成数据结构。
df = pd.DataFrame({'A': ['foo', 'bar', 'bar', 'foo', 'foo', 'foo'],
'B': ['one', 'two', 'three', 'one', 'two', 'two'],
'C':[1, 2, 3, 4, 5, 6]})
print(df, '\n')
print(df.groupby('A').sum(), '\n')
print(df.groupby('B').sum())
>>>
A B C
0 foo one 1
1 bar two 2
2 bar three 3
3 foo one 4
4 foo two 5
5 foo two 6 C
A
bar 5
foo 16 C
B
one 5
three 3
two 13
也可以按照多列分组
print(df.groupby(['A', 'B']).sum())
>>>
C
A B
bar three 3
two 2
foo one 5
two 11
Pandas 同样提供绘制图表的功能。
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2018', periods=1000))
print(ts, '\n')
ts = ts.cumsum() # 返回累计值
ts.plot()
>>>
2018-01-01 1.055229
2018-01-02 0.101467
2018-01-03 -2.083537
2018-01-04 1.178102
2018-01-05 -0.084247
...
2020-09-22 -4.316770
2020-09-23 -0.823494
2020-09-24 0.215199
2020-09-25 1.094516
2020-09-26 0.285788
Freq: D, Length: 1000, dtype: float64 Out[94]:
结果如下:
THE END!
文章结束,感谢阅读。大家有推荐的公众号可以评论区留言,共同学习,一起进步。