"""
author:张鑫
date:2021/7/2 15:27
"""
import pandas as pd
import numpy as nm
from pandas import DataFrame, Series
'''
DataFrame 是一种二维的数据结构,非常接近于电子表格或者类似 mysql 数据库的形式。
它的竖行称之为 columns,横行跟前面的 Series 一样,称之为 index,
也就是说可以通过 columns 和 index 来确定一个主句的位置。
'''
# df1 = pd.DataFrame(nm.arange(0, 9).reshape(3, 3), index=list('123'), columns=(list('123')))
# df2 = pd.DataFrame(nm.arange(10, 19).reshape(3, 3), index=list('abc'), columns=list('ABC'))
'''
data = {'姓名': ['路明非', '上杉绘梨衣', '凯撒', '楚子航', '酒德麻衣', '乌鸦', '路鸣泽', '昂热'], '性别': ['男', '女', '男', '男', '女', '男', '男', '男'],
'年龄': [20, 18, 20, 19, 22, nm.NaN, pd.NaT, 1], '言灵等级': ['s', 's', 'a', 'a', 'a', 'a', 's', 's']}
s = DataFrame(data)
s.to_csv('卡塞尔.csv')
# shape:维度,第一个是行,第二个是列
print(s.shape)
# 数据表信息,包括维度,大小,列名称,数据格式
print(s.info())
print('成功')
# 数据类型
print(s.dtypes)
# 是否是空值
print(s.isnull())
# 某个字段是否是空值
print(s['姓名'].isnull())
# 查看列的唯一值,自动去重
print(s['姓名'].unique())
# values返回数据表数值,不包含标头,以数组的形式返回
print(s.values)
# 查看列名称
print(s.columns)
# 前三行信息
print(s.head(3))
# 后三行信息
print(s.tail(3))
# 去除空值所在的行,any是这行中有空格,pandas中的pd.Nat和numpy中的nm.NAN或者nm.NAN(nm单永辉保留一位小数)
print(s.dropna(how='any'))
# all是这行全是空格
print(s.dropna(how='all'))
print(s.dropna(thresh=1))
# subset删除在subset选取的字段中的含有空值的行
print(s.dropna(subset=['姓名', '年龄']))
# 数组维度
print(s.ndim)
print(s.describe)
# 最大值
print(s.max())
# 最小值
print(s.min())
# fillna是填充,可以填充任意字符
print(s.fillna(value=0))
print(s.fillna(value='123'))
print(s.sort_index())
# ascending=true是升序,flase是降序
print(s.sort_values(by='年龄', ascending=False))
# 默认升序
print(s.sort_values(by='性别'))
'''
'''
这是定义一个 DataFrame 对象的常用方法——使用 dict 定义。
字典的“键”("name","marks","price")就是 DataFrame 的 columns 的值(名称),
字典中每个“键”的“值”是一个列表,它们就是那一竖列中的具体填充数据。上面的定义中没有确定索引,
所以,按照惯例(Series 中已经形成的惯例)就是从 0 开始的整数。从上面的结果中很明显表示出来,
这就是一个二维的数据结构(类似 excel 或者 mysql 中的查看效果)。
上面的数据显示中,columns 的顺序没有规定,就如同字典中键的顺序一样,
但是在 DataFrame 中,columns 跟字典键相比,有一个明显不同,就是其顺序可以被规定,向下面这样做:
'''
'''
data = {'姓名': ['路明非', '上杉绘梨衣'], '性别': ['男', '女'], '年龄': [20, 18], '言灵等级': ['s', 's']}
# 列名
coulmns = ['姓名', '年龄', '性别', '言灵等级']
# 行名
index = ['cp1', 'cp2']
s = DataFrame(data, index, coulmns)
print(s)
'''
'''
采用字典套字典的方式储存,
第一层的键是列名
第二层的键是行名
第二层的值是属性名
data = {'name': {'username1': '路明非', 'username2': '上杉绘梨衣'},
'age': {'username1': 20, 'username2': 18}}
s = DataFrame(data)
# print(s)
# 给同一列赋值
# 先建一个空列
index = ['name', 'age', 'sex']
s['sex'] = '男'
# print(s)
# 可以单独设置值,以列名,行名的顺序确定位置
s['sex']['username2'] = '女'
print(s)
'''
'''
# 根据标签名查找
# 行列,查询一个值
print(s.loc[1, '姓名'])
# 行,查询一行值
print(s.loc[0])
# 一行多列,多个值用[]包裹
print(s.loc[0, ['姓名', '性别']])
# 一列多行,多个值用[]包裹
print(s.loc[[0, 1], '性别'])
# 多行多列,可以不连续
print(s.loc[[0, 3], ['姓名', '性别']])
# 多行多列,冒号两边是边界
print(s.loc[1:5, '姓名':'言灵等级'])
'''
'''
# 通过位置查找,和loc类似
print(s.iloc[0, 0])
print(s.iloc[0:5, 0:5])
'''
'''
# 对查询的结果进行赋值,改变原表格
s.loc[0,'姓名']='sakura'
print(s)
# 娶不到右边界
s.iloc[0:2,1:3]=0
print(s)
'''
'''
# 普通布尔索引
# 对某一列进行索引判断,多个条件用&连接,条件用()括起来
print(s['年龄'] < 20)
print((s['年龄'] < 20) & (s['年龄'] >5) )
# 不在(5,20)之间
print((s['年龄'] < 20) != (s['年龄'] >5) )
# 判断null值
print(s.isnull())
# 判断不是null值
print(s.notnull())
# 删除null所在行
print(s.dropna(axis=0))
print(s.dropna())
# 删除null所在的列
print(s.dropna(axis=1))
# 删除有空值的行
print(s.dropna(how='any'))
# 删除所有值均为空值的行
print(s.dropna(how='all'))
# 是否在原表上修改
print(s.dropna(inplace=False))
# 填充0
print(s.fillna(0))
# mean()平均值
print(s.fillna(0).mean())
'''
'''
# 集合
# 行索引相同,显示值,不同显示NAN
# 并集
print(df1.join(df2))
print(df2.join(df1))
# 交集
print(df1.merge(df2, left_index=True, right_index=True))
print(pd.merge(df1, df2, left_index=True, right_index=True))
print(pd.merge(df1, df2,left_on='1',right_on='A'))
gr = s.groupby(by='年龄')
for temp in gr:
# print(temp)
# print(temp[0])
print(temp[1])
'''
'''
# 每列的个数
# print(s.count())
print(s['年龄'].count())
# 其中一列的个数
# print(s['年龄'].count())
# 平均数,包含空值
print(s['年龄'].mean())
# 和
print(s['年龄'].sum())
# 算数中位数,中间的数,如果是奇数位,则是他自己,偶数位是他们的平均值
print(s['年龄'].median())
# 标准差,方差的平方根
print(s['年龄'].std())
# 方差,各个数和平均值的差值的平均值的平均数
print(s['年龄'].var())
# 最大值
print(s['年龄'].max())
# 最小值
print(s['年龄'].min())
print(s['年龄'],type(s['年龄']))
print(s[['年龄']],type(s[['年龄']]))
'''
'''
# 索引和复合索引
# nm是numpy简写,
# arange(12)代表0到11这12个数字
# reshape(3,4)代表着12的数字时3*4分步
# index=list('abc')代表着列标头是a,b,c
# columns='ABCD'代表行表头是ABCD
df1 = pd.DataFrame(nm.arange(12).reshape(3, 4), index=list('abc'), columns=list('ABCD'))
print(df1)
# 行标头转换
df1.index = list('123')
print(df1)
# reindex重命名的行标头
# 如果有未改名的保留原数值,原值保留一位小数
# 不存在的填充值为nan
df2 = df1.reindex(list('1we'))
print(df2)
# set_index行列转换,默认删除此列,且不在原数组上修改
df3 = df1.set_index(list('AB'))
print(df3)
# swaplevel互换索引值,方便取值
df4 = df3.swaplevel()
print(df4)
'''
# 时间序列
# pd.date_rane(a,b)从a到b这段时间
# df1 = pd.date_range('2021/01/01', '2021/06/01')
# df2 = pd.date_range('2021/07/01', '2021/12/01')
# print(df1)
# print(df2)
# periods周期是10,每次增加1
index = pd.date_range('20210101', periods=30)
# nm.random.rand(10)返回10个0到1的值,不包括1
df1 = pd.Series(nm.arange(1, 31), index=index)
# print(df1)
# DataFrame中的重采样/升采样/降采样,resample(时间间隔)
# 重采样,常用于制作金融行业的开盘收盘,最高价最低价表格
# 升采样,每次增加10,比初始值增加大
# 10小时聚合一次,结果是左闭右开的0,10之类的数
# count是10小时之内的个数
# 0点到第二天之前算1
# 无论何时到第二天算1
# 其他为0
print(df1.resample('10H').count())
# 降采样,每次增加二,比初始值增加小
print(df1.resample('7d').count())