简单来说,Numpy就是用来进行矩阵计算的,而Pandas则基于Numpy,丰富并简化了Numpy的操作
Numpy
基础操作
import numpy as np
array = np.array([[1, 2, 3],
[2, 3, 4]], dtype=np.int) #dtype即元素数据类型
a = np.zeros((3, 4)) # 3行4列的零矩阵
vec = np.arange(10, 20) # 从10到20的向量
mat_range = np.arange(12).reshape((3, 4)) # 从10到20的3行4列的矩阵
vec_line = np.linspace(1, 10, 3) # 从1到10分为3个元素的向量,使得相邻元素差值一致
print(array.ndim) # 维度
print(array.shape) # (2, 3)
print(array.size) # 元素个数
print(array.dtype)
b = a.copy() # 深拷贝
基础运算
a = np.array([10, 20, 30, 40]).reshape((2, 2))
b = np.arange(4).reshape((2, 2))
print(a.T) # 矩阵转置
c = 10 * np.sin(a) # 对a每个元素求sin再乘10
print(b < 3) # 所有元素比较 [ True True True False]
c = a*b # 对应元素相乘
c = np.dot(a, b) # 矩阵乘法
rand = np.random.random((2, 4)) # 随机矩阵
print(np.sum(a, axis=0)) # 行相加,axis理解为shape的索引
np.min(rand)
np.max(rand)
基础运算(二)
a = np.arange(2, 14).reshape((3, 4))
b = np.random.random((3, 4))
print(a)
print(np.argmax(a)) # 返回最大值索引
print(np.argmin(a))
print(np.average(a)) # 平均值
print(np.cumsum(a)) # 前缀和
print(np.diff(a)) # 一阶差分
print(np.nonzero(a))
print(np.clip(a, 5, 9)) # 将元素限制在[5,9]
索引和迭代
a = np.arange(3, 15).reshape((3, 4))
print(a[2, 1]) # 第二行第一列元素
print(a[:, 1]) # 第一列元素
for row in a:
print(row)
for col in a.T:
print(col)
for item in a.flat: # 遍历每个元素
print(item)
合并和分割
a = np.array([1, 1, 1])
b = np.array([2, 2, 2])
print(a[:, np.newaxis]) # 把1维的行向量变成2维列向量
print(np.vstack((a, b))) # 上下合并
print(np.hstack((a, b))) # 左右合并
a = np.arange(12).reshape((3, 4))
print(np.split(a, 2, axis=1)) # 纵向等分为2部分
print(np.array_split(a, 3, axis=1)) # 纵向不等分为3部分
Pandas
如果说numpy相当于一个list,那么Pandas就相当于一个dict
简单来说,当数据的维度比较大的时候,单纯地通过numpy中的数字索引来访问元素显得有些意义不明,我们希望给某一行,某一列甚至某个单元的元素一个名称,简化操作的同时丰富每一行的代码的语义和可读性,这就是Pandas
基本操作
在学习基本操作之前,我们必须明确的一点是:
一般来说,使用矩阵组织数据的是以行为单元的,什么意思呢?就是多组结构一致的数据往往表现在矩阵里是多行。因此从列的角度看每一列是多组数据的同一类型数据。这也是为什么在Pandas里行方向的labels称作index,因为它跟一般意义的索引没有本质区别,都是表示数据的序号
Pandas中最常用的两种数据类型是:Series和DataFrame
import pandas as pd
import numpy as np
s = pd.Series([1, 3, 6, 7, 44, np.nan, 3.4], index=[7]*7) # 相当于一维的ndarray加上标签
data = pd.DataFrame(np.arange(12).reshape(
(3, 4)), index=np.arange(3), columns=['a', 'b', 'c', 'd'])
# 相当于矩阵加上行标签和列标签,index表示行标签,columns表示列标签
print(data.index) # 行labels
print(data.columns) # 列labels
print(data.values)
print(data.describe()) # 按列输出统计数据
data = data.sort_index(axis=0, ascending=False) # 对行labels排序,从大到小
data = data.sort_values(by='a', axis=0) # 指定列labels按行排序
数据选择及更改
dates = pd.date_range('20190329', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6, 4)),
index=dates, columns=['a', 'b', 'c', 'd'])
print(df['a'], df.a, sep='\n') # 输出标签为'a‘的列
print(df[0:3], df['20190329':'20190331'], sep='\n') # 输出前三行数据
print(df.loc['20190329'])
print(df.loc[:, ['a', 'b']]) # loc基于标签名
print(df.iloc[3:5, 1:3]) # iloc基于行列的绝对数字(index)
print(df[df.a > 8]) # 筛选出a大于8的行
# 更改数据
df.iloc[2, 2] = 111
df.loc['20190329', 'b'] = 333
df.a[df.a > 4] = 0 # 把大于4的a列赋值为0
df['f'] = np.nan # 动态添加新列
处理丢失数据
dates = pd.date_range('20190329', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6, 4)),
index=dates, columns=['a', 'b', 'c', 'd'])
df.iloc[0, 1] = np.nan
df.iloc[1, 2] = np.nan
print(df.fillna(value=0)) # 填充nan为0
print(df.dropna(axis=0, how='any')) # 丢失存在nan的行
print(df.isnull()) # nan的位置为True,其余为False
print(np.any(df.isnull()) == True) # 判断整个矩阵是否存在nan
简单IO
data = pd.read_csv('data.csv', sep=',')
pd.to_pickle(data, 'data.pickle')
data = pd.read_pickle('data.pickle')
合并
import pandas as pd
import numpy as np
# concat
df1 = pd.DataFrame(np.ones((3, 4))*0, columns=['a', 'b', 'c', 'd'])
df2 = pd.DataFrame(np.ones((3, 4))*1, columns=['a', 'b', 'c', 'd'])
df3 = pd.DataFrame(np.ones((3, 4))*2, columns=['a', 'b', 'c', 'd'])
print(df1, df2, df3, sep='\n\n')
res = pd.concat([df1, df2, df3], axis=0,
ignore_index=True, join='inner') # 按行合并(即纵向),index重新计算
# inner模式删去非公共的列标签对应的列,outer则会保留,同时用nan填充
res = res.append(pd.Series([0, 1, 2, 3], index=[
'a', 'b', 'c', 'd']), ignore_index=True) # 添加一个Series
# 基于key的合并请参考merge函数,和sql中的内外连接非常相似,此处不赘述各参数的用法,需要时查询文档即可
pd.merge()
网友评论