P a n d a s 库 基 本 使 用 Pandas库基本使用 Pandas库基本使用
引子
Numpy 在向量化的数值计算中表现优异
但是在处理更灵活、复杂的数据任务:
如为数据添加标签、处理缺失值、分组和透视表等方面
Numpy显得力不从心
而基于Numpy构建的Pandas库,提供了使得数据分析变得更快更简单的高级数据结构和操作工具
1 对象创建
1.1 Pandas Series对象
Series 是带标签数据的一维数组
Series对象的创建
通用结构: pd.Series(data, index=index, dtype=dtype)
data:数据,可以是列表,字典或Numpy数组
index:索引,为可选参数
dtype: 数据类型,为可选参数
1、用列表创建
- index缺省,默认为整数序列
import pandas as pd
data = pd.Series([1.5, 3, 4.5, 6])
data
- 增加index
data = pd.Series([1.5, 3, 4.5, 6], index=["a", "b", "c", "d"])
data
-
增加数据类型
缺省则从传入的数据自动判断
data = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
data
data = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"], dtype="float")
data
注意:数据支持多种类型
data = pd.Series([1, 2, "3", 4], index=["a", "b", "c", "d"])
data
data["a"]
data["c"]
数据类型可被强制改变
data = pd.Series([1, 2, "3", 4], index=["a", "b", "c", "d"], dtype=float)
data
data["c"]
data = pd.Series([1, 2, "a", 4], index=["a", "b", "c", "d"], dtype=float)
data
2、用一维numpy数组创建
import numpy as np
x = np.arange(5)
pd.Series(x)
3、用字典创建
- 默认以键为index 值为data
population_dict = {"BeiJing": 2154,
"ShangHai": 2424,
"ShenZhen": 1303,
"HangZhou": 981 }
population = pd.Series(population_dict)
population
- 字典创建,如果指定index,则会到字典的键中筛选,找不到的,值设为NaN
population = pd.Series(population_dict, index=["BeiJing", "HangZhou", "c", "d"])
population
4、data为标量的情况
pd.Series(5, index=[100, 200, 300])
1.2 Pandas DataFrame对象
DataFrame 是带标签数据的多维数组
DataFrame对象的创建
通用结构: pd.DataFrame(data, index=index, columns=columns)
data:数据,可以是列表,字典或Numpy数组
index:索引,为可选参数
columns: 列标签,为可选参数
1、通过Series对象创建
population_dict = {"BeiJing": 2154,
"ShangHai": 2424,
"ShenZhen": 1303,
"HangZhou": 981 }
population = pd.Series(population_dict)
pd.DataFrame(population)
pd.DataFrame(population, columns=["population"])
2、通过Series对象字典创建
GDP_dict = {"BeiJing": 30320,
"ShangHai": 32680,
"ShenZhen": 24222,
"HangZhou": 13468 }
GDP = pd.Series(GDP_dict)
GDP
pd.DataFrame({"population": population,
"GDP": GDP})
注意:数量不够的会自动补齐
pd.DataFrame({"population": population,
"GDP": GDP,
"country": "China"})
3、通过字典列表对象创建
- 字典索引作为index,字典键作为columns
import numpy as np
import pandas as pd
data = [{"a": i, "b": 2*i} for i in range(3)]
data
data = pd.DataFrame(data)
data
data1 = data["a"].copy()
data1
data1[0] = 10
data1
data
- 不存在的键,会默认值为NaN
data = [{"a": 1, "b":1},{"b": 3, "c":4}]
data
pd.DataFrame(data)
4、通过Numpy二维数组创建
data = np.random.randint(10, size=(3, 2))
data
pd.DataFrame(data, columns=["foo", "bar"], index=["a", "b", "c"])
2 DataFrame性质
1、属性
data = pd.DataFrame({"pop": population, "GDP": GDP})
data
(1)df.values 返回numpy数组表示的数据
data.values
(2)df.index 返回行索引
data.index
(3)df.columns 返回列索引
data.columns
(4)df.shape 形状
data.shape
(5) pd.size 大小
data.size
(6)pd.dtypes 返回每列数据类型
data.dtypes
2、索引
data
(1)获取列
- 字典式
data["pop"]
data[["GDP", "pop"]]
- 对象属性式
data.GDP
(2)获取行
- 绝对索引 df.loc
data.loc["BeiJing"]
data.loc[["BeiJing", "HangZhou"]]
- 相对索引 df.iloc
data
data.iloc[0]
data.iloc[[1, 3]]
(3)获取标量
data
data.loc["BeiJing", "GDP"]
data.iloc[0, 1]
data.values[0][1]
(4)Series对象的索引
type(data.GDP)
GDP
GDP["BeiJing"]
3、切片
dates = pd.date_range(start='2019-01-01', periods=6)
dates
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=["A", "B", "C", "D"])
df
(1)行切片
df["2019-01-01": "2019-01-03"]
df.loc["2019-01-01": "2019-01-03"]
df.iloc[0: 3]
(2)列切片
df
df.loc[:, "A": "C"]
df.iloc[:, 0: 3]
(3)多种多样的取值
df
* 行、列同时切片
df.loc["2019-01-02": "2019-01-03", "C":"D"]
df.iloc[1: 3, 2:]
- 行切片,列分散取值
df.loc["2019-01-04": "2019-01-06", ["A", "C"]]
df.iloc[3:, [0, 2]]
- 行分散取值,列切片
df.loc[["2019-01-02", "2019-01-06"], "C": "D"]
df.iloc[[1, 5], 0: 3]
- 行、列均分散取值
df.loc[["2019-01-04", "2019-01-06"], ["A", "D"]]
df.iloc[[1, 5], [0, 3]]
4、布尔索引
df
df > 0
df[df > 0]
df.A > 0
df[df.A > 0]
- isin()方法
df2 = df.copy()
df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three']
df2
ind = df2["E"].isin(["two", "four"])
ind
df2[ind]
(5)赋值
df
- DataFrame 增加新列
s1 = pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range('20190101', periods=6))
s1
df["E"] = s1
df
- 修改赋值
df.loc["2019-01-01", "A"] = 0
df
df.iloc[0, 1] = 0
df
df["D"] = np.array([5]*len(df)) # 可简化成df["D"] = 5
df
- 修改index和columns
df.index = [i for i in range(len(df))]
df
df.columns = [i for i in range(df.shape[1])]
df
3 数值运算及统计分析
1、数据的查看
import pandas as pd
import numpy as np
dates = pd.date_range(start='2019-01-01', periods=6)
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=["A", "B", "C", "D"])
df
(1)查看前面的行
df.head() # 默认5行
df.head(2)
(2)查看后面的行
df.tail() # 默认5行
df.tail(3)
(3)查看总体信息
df.iloc[0, 3] = np.nan
df
df.info()
2、Numpy通用函数同样适用于Pandas
(1)向量化运算
x = pd.DataFrame(np.arange(4).reshape(1, 4))
x
x+5
np.exp(x)
y = pd.DataFrame(np.arange(4,8).reshape(1, 4))
y
x*y
(2)矩阵化运算
np.random.seed(42)
x = pd.DataFrame(np.random.randint(10, size=(30, 30)))
x
- 转置
z = x.T
z
np.random.seed(1)
y = pd.DataFrame(np.random.randint(10, size=(30, 30)))
y
x.dot(y)
%timeit x.dot(y)
%timeit np.dot(x, y)
- 执行相同运算,Numpy与Pandas的对比
x1 = np.array(x)
x1
y1 = np.array(y)
y1
%timeit x1.dot(y1)
%timeit np.dot(x1, y1)
%timeit np.dot(x.values, y.values)
x2 = list(x1)
y2 = list(y1)
x3 = []
y3 = []
for i in x2:
res = []
for j in i:
res.append(int(j))
x3.append(res)
for i in y2:
res = []
for j in i:
res.append(int(j))
y3.append(res)
def f(x, y):
res = []
for i in range(len(x)):
row = []
for j in range(len(y[0])):
sum_row = 0
for k in range(len(x[0])):
sum_row += x[i][k]*y[k][j]
row.append(sum_row)
res.append(row)
return res
%timeit f(x3, y3)
一般来说,纯粹的计算在Numpy里执行的更快
Numpy更侧重于计算,Pandas更侧重于数据处理
(3)广播运算
np.random.seed(42)
x = pd.DataFrame(np.random.randint(10, size=(3, 3)), columns=list("ABC"))
x
- 按行广播
x.iloc[0]
x/x.iloc[0]
- 按列广播
x.A
x.div(x.A, axis=0) # add sub div mul
x.div(x.iloc[0], axis=1)
3、新的用法
(1)索引对齐
A = pd.DataFrame(np.random.randint(0, 20, size=(2, 2)), columns=list("AB"))
A
B = pd.DataFrame(np.random.randint(0, 10, size=(3, 3)), columns=list("ABC"))
B
- pandas会自动对齐两个对象的索引,没有的值用np.nan表示
A+B
- 缺省值也可用fill_value来填充
A.add(B, fill_value=0)
A*B
(2)统计相关
- 数据种类统计
y = np.random.randint(3, size=20)
y
np.unique(y)
from collections import Counter
Counter(y)
y1 = pd.DataFrame(y, columns=["A"])
y1
np.unique(y1)
y1["A"].value_counts()
- 产生新的结果,并进行排序
population_dict = {"BeiJing": 2154,
"ShangHai": 2424,
"ShenZhen": 1303,
"HangZhou": 981 }
population = pd.Series(population_dict)
GDP_dict = {"BeiJing": 30320,
"ShangHai": 32680,
"ShenZhen": 24222,
"HangZhou": 13468 }
GDP = pd.Series(GDP_dict)
city_info = pd.DataFrame({"population": population,"GDP": GDP})
city_info
city_info["per_GDP"] = city_info["GDP"]/city_info["population"]
city_info
递增排序
city_info.sort_values(by="per_GDP")
递减排序
city_info.sort_values(by="per_GDP", ascending=False)
按轴进行排序
data = pd.DataFrame(np.random.randint(20, size=(3, 4)), index=[2, 1, 0], columns=list("CBAD"))
data
行排序
data.sort_index()
列排序
data.sort_index(axis=1)
data.sort_index(axis=1, ascending=False)
- 统计方法
df = pd.DataFrame(np.random.normal(2, 4, size=(6, 4)),columns=list("ABCD"))
df
非空个数
df.count()
求和
df.sum()
df.sum(axis=1)
最大值 最小值
df.min()
df.max(axis=1)
df
df.idxmax()
均值
df.mean()
方差
df.var()
标准差
df.std()
中位数
df.median()
众数
data = pd.DataFrame(np.random.randint(5, size=(10, 2)), columns=list("AB"))
data