Pandas数据分析教程,由浅入深讲解(一)
一、Pandas核心数据类型
(一)什么是Pandas
Pandas是Python用于数据分析的一个扩展程序库,名字衍生于术语“panel data(面板数据)”和“Python data analysis”;Pandas可以从各种文件格式导入数据,比如CSV、JSON、SQL、Excel等;并可以对各种数据进行运算操作,比如归并、再成形、选择以及数据清洗和加工特征。
Pandas的主要数据结构是Series(一维)和DataFrame(二维数据)。
(二)Series
Series是一种类似于字典(dict-like)的一维数组的对象,由两部分组成:1、values:一组数据(ndarray类型);2、index:相关的数据索引标签。
python中字典是无序的,但Series却是有序的。
1、series的构造
import numpy as np import pandas as pd # pandas中的series则是有序的,又是dict-like的 arr1 = np.random.randint(0, 10, size = 5) # 隐式索引,定义时候未明确索引名的则按0,1,2...去作为其内容的对应索引 s1 = pd.Series(data = [1, 3, 5, 7]) # 显式索引,通过index设置;未显式设置则默认用隐式索引 s2 = pd.Series(data = arr1, index = ["A", "B", "C", "D", "E"])
s1和s2输出如下:
# s1 0 1 1 3 2 5 3 7 dtype: int64 # s2 A 10 B 6 C 2 D 0 E 1 dtype: int32
上面的s1的构造是通过列表;而s2的构造则是先利用np中的ndarray构造了一个arr1,再将arr1作为s2的内容。
但需要注意的是利用ndarray构造的是引用对象,Series的内容实质还是指向原先ndarray创建的内存,即引用。
而利用列表构造得到是副本对象,即Series会新建一块内存区域存放原先列表的内容,作为自己的内容。
# 使用字典构造Series,字典的键就默认设置为显式索引,values作为值 dict1 = { "Name":"Tony", "Age":18, "City":"Nanjing" } s3 = pd.Series(data = dict1)
当然,还可以直接通过字典去构造Series,字典的键就自动设置为Series的显式索引,values自动设置为Series的值。
在使用字典构造时,有时候我们可能只需要原字典中的某些项,那么就可以通过index设置
dict2 = { "Name":"Jack", "Age":18, "City":"NJ", "Hobby":"Soccer" } # 如果Series中只需要原字典中键Name和city对应的内容,则如下: s4 = pd.Series(data = dict2, index = ["Name", "City"]) s4 """ Name Tony City Nanjing dtype: object """ # 如果Series中除了原字典中的Hobby之外,还需要其他索引,则如下: s5 = pd.Series(data = dict2, index = ["Hobby", "Birthday", "Sex"]) s5 """ Hobby Soccer Birthday NaN Sex NaN dtype: object """
最后一种构造方法就是使用一个标量(常量或变量),这种方法必须指定index,标量会被赋值匹配到每一个index.
city_index = ["南京", "上海", "武汉", "广州", "福州"] s6 = pd.Series(data = 18888, index = city_index) s6 """ 南京 18888 上海 18888 武汉 18888 广州 18888 福州 18888 dtype: int64 """
2、Series的重要属性
*name返回Series对象的名字;*shape返回Series对象的形状;*size返回Series对象的元素个数;*index返回Series对象的显式索引;*values返回Series对象的所有元素值
可以通过Series变量名.索引名的方式获取对应的value值,也可以通过类似字典的方式即Series变量名[索引名]获取
import numpy as np import pandas as pd s1 = pd.Series(data = ["Tom", 12, "melburn", "male"], index = ["nickname", "age", "city", "sex"]) print(s1.nickname, s1.city, s1["sex"], s1["age"]) # 输出 Tom melburn male 12
name属性可以在创建Series对象时设置:
s2 = pd.Series(data = [1, 3, 5, 7], index = list("ABCD"), name = "num_series") print(s2.name)
shape可以简单理解为元素个数,因为Series是一维的,在超过一维情况下,才会体会到“shape(形状)”的感觉
s2 = pd.Series(data = [1, 3, 5, 7], index = list("ABCD"), name = "num_series") print(s2.name) # num_series print(s2.shape) # (4,) print(s2.dtype) # int64 print(s2.size) # 4 print(s2.index) # Index(['A', 'B', 'C', 'D'], dtype='object') print(s2.values) # [1 3 5 7]
3、Series的数学运算
(1)与非pandas对象的运算
广播机制,将数据广播给每一个Series对象的值再进行运算
如下,与int整型数据运算:
s1 = pd.Series(data = [1, 2, 3], index = list("ABC")) print(s1 + 10) # 输出 A 11 B 12 C 13 dtype: int64 print(s1 * 2) # 输出 A 2 B 4 C 6 dtype: int64
(2)Numpy functions运算
x = np.power(s1, 3) print(x) # 输出 A 1 B 8 C 27 dtype: int64
(3)Series对象之间的运算
遵循索引对齐原则;如果对不齐,则补全空值,使用add/sub/mul/div函数处理空值
s1 = pd.Series(data = np.array([2, 3, 4]), index = list("ABC")) s2 = pd.Series(data = np.array([10, 12, 15]), index = list("ABC")) print(s1 + s2) # 输出 A 12 B 15 C 19 dtype: int64
上面代码可能看出结果很简单,很自然,继续看下面:
s1 = pd.Series(data = np.array([2, 3, 4]), index = list("ABC")) s2 = pd.Series(data = np.array([10, 12, 15]), index = list("BCA")) print(s1 + s2) # 输出 A 17 B 13 C 16 dtype: int64
上面s2的index顺序与上面不一样了,但运算依旧是按照匹配相同索引,即相同索引的内容进行运算,这才是“索引对齐”的真实含义。
下面是索引对不齐的情况:
s1 = pd.Series(data = np.array([2, 3, 4]), index = list("ABC")) s2 = pd.Series(data = np.array([10, 12, 15]), index = list("ACD")) print(s1 + s2) # 输出 A 12.0 B NaN C 16.0 D NaN dtype: float64
s1中有B无D,s2中有D无B;两者都有A和C,所以相加之后索引A和C的值可以直接求
但B和D因为都涉及到空值,只要参与运算的一方是 NaN,结果就是 NaN,这是 NumPy / pandas 的统一规则
“为什么 pandas 不“偷偷帮我把缺失值当成 0”?那样看起来更方便啊?”
因为把“缺失(NaN)”当成“0”,在大多数真实数据分析中是危险且误导的。
NaN :Not a Number.即“不是一个数据,无法知晓,未定义”。
在明确知晓运算对象中存在索引缺失、对不齐的情况下,可以通过补齐的方式:
s1 = pd.Series(data = np.array([2, 3, 4]), index = list("ABC")) s2 = pd.Series(data = np.array([10, 12, 15]), index = list("ACD")) s1 = s1.reindex(s1.index.union(s2.index), fill_value=0) print(s1) # 输出 A 2 B 3 C 4 D 0 dtype: int64 s2 = s2.reindex(s1.index, fill_value=0) print(s2) # 输出 A 10 B 0 C 12 D 15 dtype: int64 print(s1 + s2) # 输出 A 12 B 3 C 16 D 15 dtype: int64
浙公网安备 33010602011771号