最近学习数据分析,经常使用到pandas,写个blog加深一下印象
文档地址
用作范例的数据库文件:
链接: https://pan.baidu.com/s/1Cz9PwQuw1SrZhtQ-iuXg1g 提取码: jmnx
1. DataFrame的增删改查
1. 1 增
1. 1. 1读取文件
pandas支持多种读取方式,如sql, csv等
函数名称 | 参数 | 备注 |
---|---|---|
pd.read_csv(filename ,encoding=‘gbk’, index_col) | filename, 文件地址 | |
encoding, 编码方式 | gbk才是excel可以识别的方式, gb2312和utf-8都会乱码 | |
index_col, 字符串 | 指定的行标签名称 | |
pd.read_excel(filename ,encoding=‘gbk’) | filename, 文件地址 | |
pd.read_sql(query, con) | query, SQL查询语句 | SQL语法 |
con, 连接的数据库 | 在使用这个函数之前要先连接上一个数据库 | |
pd.read_json(json_string) | ||
pd.read_clipboard() |
实例1:读取一个sql的数据库
con = sqlite3.connect("stock_data.db") # 使用sqlite3,方便简单
pd.read_sql("SELECT * FROM data", con=con)
con.close() # 用完关掉是个好习惯
1. 1. 2 手动创建
df = pd.DataFrame(data, index, columns, dtype)
参数名称 | 数据类型 | 解释 |
---|---|---|
data | 二维数据即可 | |
index | 一维数据,Series或者list | |
columns | 一维数据, Series或者list | |
dtype | 数据类型名称, 如int, float |
实例1:生成一个0-23的 6* 4矩阵
dates = pd.date_range("20200101", periods=6) # 生成一个日期标签,该函数后面会讲
df = pd.DataFrame(np.arange(24).reshape((6, 4)), index=dates, columns=range(0, 4))
实例2:用字典创建一个DataFrame
# 用字典创建的二维数据,注意,key是列标签,行标签是序号
# 即a 和 b都是列,行标签是0123……
# 这里自动补齐了a列缺失的数据,全为1
df = pd.DataFrame({
'a':1,
'b':[1, 2, 3]
})
1. 1. 3 在已有DataFrame上增加数据
1.1.3.1 纵向合并
df = df.append(DataFrame)
参数名称 | 数据类型 | 解释 |
---|---|---|
DataFrame | DataFrame | 如果两个DataFrame的行标签或列标签不一致,则会自动添加,添加值为NaN |
实例1:纵向合并数据
# 获取数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con)[:5]
con.close()
print(df)
print(df.append(df.iloc[:5]))
原数据:
append增加后的数据:
1.1.3.2 横向合并
df = df.concat([df, df1], axis=1)
其实concat横向纵向皆可,修改axis即可,1是横向,0是纵向
参数名称 | 数据类型 | 解释 |
---|---|---|
Union[DataFrame] | [DataFrame, DataFrame1 ……] | 放要合并的DataFrame |
axis | 合并的方向,如果横向合并(即axis=1)的时候,索引相同项会自动合并,很方便 |
1.1.3.3 添加一列数据
df[标签] = data
参数名称 | 数据类型 | 解释 |
---|---|---|
标签 | 字符串 | 要添加的那一列的标签名称 |
data | 列表/Series | 要添加那一列的数据,必须和现有的行数一致 |
1.1.3.4 添加一行数据
df.loc[标签] = data
参数名称 | 数据类型 | 解释 |
---|---|---|
标签 | 行标签字符串 | |
data | 列表/Series | 要添加那一行的数据,必须和现有的列数一致 |
1.2 删
1.2.1 精确删除行/列
df.drop([标签]/df.index[], axis)
参数名称 | 数据类型 | 解释 |
---|---|---|
标签 | 列表, 中间是标签的名称 | 可以是行标签也可以是列标签,取决于axis的方向 |
df.index[] | 根据行号删除,如df.index[0:3] 就代表删除前三行 | |
axis | 方向, 1代表删除列,0代表删除行 | 默认值是0 |
实例1:删除行/列
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con)[:5].set_index('date') # 注意这里是指定了date为行标签
con.close()
# 精确删除
df = df.drop(['open'], axis=1) # 删除open列
df = df.drop(['2018-01-02'], axis=0) # 删除2018-01-02 行
df = df.drop(df.index[0]) # 删除当前的第一行
print(df)
1.3 改
1.3.1 修改一列的数据类型
有时候导入了数据之后,在执行运算的时候发现某一列数据全是字符串,想要改成数字的时候,就需要修改数据类型了
pd.to_numeric(列)
pd.to_datetime(列)
pd.to_timedelta(列)
参数名称 | 数据类型 | 解释 |
---|---|---|
列 | Series | 将该列数据改变为对应类型 |
实例1:修改数据类型为数字
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con)[:5].set_index('date') # 注意这里是指定了date为行标签
con.close()
df['open'] = pd.to_numeric(df['open']) # 将数据类型转变为数字
print(df['open'].cumsum()) # 执行累加进行验证
1.3.2 修改许多列的数据类型
df.apply(方法, errors)
参数名称 | 数据类型 | 解释 |
---|---|---|
方法 | 要应用的方法, 如pd.to_numeric | 注意没有括号 |
errors | 字符串, 如"igonre" | 如果不能改变的情况下要做什么,“ignore”代表不管他 |
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con)[:5].set_index('date') # 注意这里是指定了date为行标签
con.close()
df = df.apply(pd.to_numeric, errors='ignore')
print(df['open'].cumsum()) # 执行累加进行验证
1.3.3 修改行标签
1.3.3.1 创建时指定
见 1.1.1 读取文件
1.3.3.2 创建后修改
df.set_index(列名)
1.4 查
1.4.1根据标签/行号查找
df.loc[行标签, 列标签]
参数名称 | 数据类型 | 解释 |
---|---|---|
行标签,列标签 | 可以是行列标签的字符串,也可以是切片,如df.loc[:, ‘open’] | 示例代表选择open这一列的所有行 |
df.iloc[index][列标签]
参数名称 | 数据类型 | 解释 |
---|---|---|
index | int或者切片 | 要选择的那列数据的行号,可以切片 |
列标签 | 列标签的名称 | 可选 |
实例1:选择
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con)[:5].set_index('date') # 注意这里是指定了date为行标签
con.close()
print(df.loc[:, ['open', 'close']]) # 按照loc进行选择
print(df.iloc[0:2, 0:2]) # 按照行列序号选择
print(df.iloc[0:2]['open']) # 混合选择
1.4.2 根据条件进行查找
df[逻辑判断式]
实例1:根据条件查找
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con)[:5].set_index('date') # 注意这里是指定了date为行标签
con.close()
# 先改成数字格式
df = df.apply(pd.to_numeric, errors='ignore')
# 筛选open大于6.4的,如果是False就表示小于等于6.4
print(df[(df.open > 6.4) == True])
1.4.3 查看DataFrame的属性
# 查看数据的属性,如果要修改的话也直接赋值
print(df.dtypes) # 数据的类型
print(df.columns) # 数据的列标签
print(df.index) # 数据的行标签
print(df.values) # 数据的值
3. 数据应用
3. 1 数据库的应用
3.1.1 连接数据库
** sqlite3.connect(文件名)**
参数名称 | 数据类型 | 解释 |
---|---|---|
文件名 | 字符串,是地址全称(或有默认地址路径) |
3.1.2 读取数据库
见 1.1.1 读取文件
3.1.3 插入/生成数据库
df.to_sql(name, con, if_exists, index)
参数名称 | 数据类型 | 解释 |
---|---|---|
name | 字符串 | 表名 |
con | 字符串 | 连接了的数据库 |
if_exists | 字符串 | 表如果存在要怎么做(append追加,replace删除原表,fail什么都不干) |
index | bool | 是否插入索引 |
3.2 数据的处理
3.2.1 描述数据
df.info()
df.describe()
3.2.2 一些函数
3.2.2.1 resample, 对日期标签的数据进行再采样
df.resample(rules).方法()
详见:https://www.cnblogs.com/dadadechengzi/p/7097836.html
参数名称 | 数据类型 | 解释 |
---|---|---|
rules | 字符串, 如’5D’代表以5天为一个周期进行再采样 | Y 年,M 月,D 日,H 时, T 分,S 秒 |
方法 | 采样之后要做的事情 | sum 求和,max 最大值, min 最小值, mean 平均值 |
实例1:resample再采样
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con)[:5] # 注意这里是指定了date为行标签
con.close()
# 先改成数字格式和设置行标签格式
df = df.apply(pd.to_numeric, errors='ignore')
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
# 再采样
print(df)
print(df.resample('3D').max())
3.2.2.2 qcut和value_counts将数据等分并展示
pd.qcut(x, q)
参数名称 | 数据类型 | 解释 |
---|---|---|
x | Series | 要处理的数据 |
q | int | 等分的数量 |
实例1: 等分数据并展示
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con) # 注意这里是指定了date为行标签
con.close()
# 先改成数字格式和设置行标签格式
df = df.apply(pd.to_numeric, errors='ignore')
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
cat = pd.qcut(df['open'], 10) # 等分数据
print(cat.value_counts()) # 将等分的数据统计展示出来
3.2.2.3 pct_change后一行减前一行
Dataframe.pct_change()
实例1:pct_change
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con)[:5] # 注意这里是指定了date为行标签
con.close()
# 先改成数字格式和设置行标签格式
df = df.apply(pd.to_numeric, errors='ignore')
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
print(df)
print(df.pct_change())
3.2.3 对空数据的处理
3.2.3.1 判断是否有空的数据
df.isnull()
通常用np.any() np.all()联系起来用
实例1:检查是否存在空数据
# 连接数据
con = sqlite3.connect("stock_data.db")
df = pd.read_sql("SELECT * FROM data", con) # 注意这里是指定了date为行标签
con.close()
# 先改成数字格式和设置行标签格式
df = df.apply(pd.to_numeric, errors='ignore')
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
df.iloc[0, 0] = np.nan # 将第一个数据改成空的
print(np.any(df.isnull())) # 检查是否存在空的数据
3.2.3.2 如果有空数据就丢掉
df.dropna(axis, how)
参数名称 | 数据类型 | 解释 |
---|---|---|
axis | 0或1 | 0代表纵向,1代表横向;即0丢行1丢列 |
how | 字符串 | any 只要有就丢,all 全部有才丢 |
实例1: 丢掉空数据
# 先改成数字格式和设置行标签格式
df = df.apply(pd.to_numeric, errors='ignore')
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
df.iloc[0, 0] = np.nan # 将第一个数据改成空的
print(df.dropna(axis=1, how='any')) # 如果存在空数据就丢掉该列
3.2.3.3 填充空数据
df.fillna(value)
参数名称 | 数据类型 | 解释 |
---|---|---|
value | numeric | 填充的值 |