'''

【任务要求】 利用Pandas函数完成对书籍数据进行清洗,包括数据缺失值处理、重复数据处理、 异常值处理、数据类型转换。
【任务描述】
1. 从桌面 “/03 数据清洗/”路径下“06 工程代码”文件夹中获取程序开发项目 工程代码。
2. 按照代码中的任务点要求,补充 Python 数据清洗代码,实现如下数据清洗任务:
  i. 检查缺失数据项
  ii. 对缺失“评论评分”数据项进行均值插补
  iii. 对缺失“评论作者”数据项的那条记录进行删除
  iv. 对冗余数据记录进行删除
  v. 把清洗后的数据保存至本地磁盘 “D:\\home\\清洗数据结果\\清洗 数据结果.txt” 文件中。

'''
import pandas as pd

df = pd.read_excel('titanic3.xls',sheet_name="Sheet1")
df0 = df.iloc[:20,1:6]
# print(df0)
# print(df0)
# print(df)
#   i. 检查缺失数据项
df1 = df['pclass'].isnull()#判断某一列存在的空值
# print(df1)
# print(df.isnull().any(axis=0)) #0:列,1:行
# print(df.isnull().any(axis=0).sum())
# print(df.isnull().sum())
# # print(df[df.isnull()].columns)
# print(df['body'].isnull().sum())
# print(df[df['body'].isnull()])


# print(df.duplicated())
# print(df.duplicated().sum())

# df.dropna(subset='age',axis=0,inplace=True)
# df['age'].fillna(method='fill',inplace=True)
# df['age'].fillna(method='bfill',inplace=True)
# df['age'].duplicated().sum()
# df['age'].drop_duplicates(inplace=True,keep='first')
# df['age'].drop_duplicates(inplace=False,keep='lase')

# 汇总
'''
print("---------------------------------------------------------------------------------------")
---------------------汇总----------------------------------------------------
# # 去重
# df['age'].duplicated().sum()
# df['age'].drop_duplicates(inplace=True,keep='first') #去重后保留重复数据中第一行重复的数据
# df.drop_duplicates(inplace=Ture,keep='last')  #去重后保留重复数据最后一行重复的数据

# # 对空值替补
# mean=df['age'].mean()
# df['age'].fillna(mean,inplace=True)
# df['age'].fillna(method='fill',inplace=True) #选择上一个非缺失值
# df['age].fillna(method='bfill,inplace=True) #选择下一个非缺失值

# # 对空值删除
# df.dropna(axis=0,subset='age',inplace=True)
'''
# 空值判断
'''
------------------------空值判断--------------------------------------------------
# 判断每个列是否存在空值,axis=0代表列,为1代表行,False不存在空值,True存在空值,并打印结果
print(df.isnull().any(axis=0))
# 判断每个行是否存在空值,axis=0代表列,为1代表行,False不存在空值,True存在空值,并打印结果
print(df.isnull().any(axis=1))
#按照列统计每一列缺失值的个数,并打印结果 axis默认为0按列统计,1为按行统计
print(df.isnull().sum())
#判断名字为'pclass'这一列的数据哪一个为空值,True为空,False不为空
print(df['pclass'].isnull())
#通过布尔索引获取age这一列空值所在的当前行所有的数据信息
print(df[df['age'].isnull()])
'''
# 计算函数
'''
-------------------------计算函数----------------------------------------------------------
print(df['pclass'].mean())#求平均值
print(df['pclass'].sum())#求和
print(df['pclass'].cumsum())#累加          
print(df['pclass'].cumprod())#累乘         
print(df['pclass'].std())#标准差           
print(df['pclass'].var())#方差

print(df.max(axis=0))#最大值    在调用还原之前,只选择有效的列。
print(df.min(axis=0))#最小值    在调用还原之前,只选择有效的列。
axis=0:按列求  axis=1:按行求 如果不设置axis参数,则默认求数据集中所有数的相关值
'''
# DateFrame常用属性
'''
----------------------DateFrame常用属性-------------------------------------------------------------------
print(df.shape) #数据形状(行列数目)
print(df.T)#转置(行转列,列转行)
print(df.size)#元素个数
# pandas中用dtypes,numpy中用dtype
print(df.dtypes)#元素类型      #float64型
print(type(df['pclass'])) #Series型,DateFrame型
print(df.index)#索引
print(df.columns) #列名
print(df.values)#元素
print(df.ndim)#维度数
'''
# 获取数据
'''
--------------获取数据---------------------
print(df.head(20))#获取前20行数据,默认是获取前5行
# 根据条件获取名字为'age'和'name'列的所有数据
print(df.loc[df.age>18,['age','name']])#打印数据集,(NaN的数据不参与计算)
#获取某列值:数据集['列名字即可']
print(df['age'])
#获取多列值:数据集[['列名','列名']]
print(df[['age','name']])
# 获取某一列中的部分数据,可使用loc[索引名:索引名]和iloc[索引:索引]
# loc是全闭区间,iloc是左闭右开区间
df0 = df.iloc[:20,1:6]  #1到19行,1到5列
print(df0)
# loc函数使用详解:https://www.jb51.net/article/183610.htm
'''
# 基础知识-
'''
----------------------基础知识----------------------------------------

import pandas as pd
import numpy as np

# 时间序列
index = pd.date_range('2021-01-01', periods=6)
print(index)
# 6行4列的随机数
data = np.random.randn(6, 4)
print(data)
df = pd.DataFrame(data, index=index, columns=list('abcd'))
print(df)
# 一、查询
# 查询单列
print(df.a)
print(type(df.a))
print(df['b'])
# 查询多列
print(df[['a', 'b']])
# 查询行
print(df[1:3])
print(df[::-2])
# head方法
print(df.head(3))
# tail方法
print(df.tail(2))
# loc方法,它的切片是左闭右闭
print(df.loc['2021-01-01': '2021-01-04', ['a', 'b']])
print(df)
print(df.loc[df['a'] > 0])
# iloc方法,它的切片规则是左闭右开
print(df.iloc[2:4, [1, 3]],456456456)

# 二、修改数据
df.loc['2021-01-01', 'a'] = 100
print(df)
df['a'] = 10
print(df)
# 三、添加数据
df['e'] = 12
print(df)
# 四、删除数据 
df_drop = df.drop('e', axis=1)
print(df_drop)
# 原表生效
df.drop('2021-01-01', axis=0, inplace=True)
print(df)
axis:删除操作的轴向,0代表删行,1代表删列

# 3.4 删除数据
# 删除某列或某行数据需要用到pandas提供的方法drop。
# 语法如下
# 参数说明
# labels:指定要删除的行或列标签
# axis:删除操作的轴向,0代表删行,1代表删列
# index:指定要删的行标签
# columns:指定要删的列标签
# inplace:是否在原数据上修改,默认为False,表示不修改原数据,此时会返回删除后的DataFrame,设置为True则
# 会修改原数据
print("---------------------------------------------------------------------------------------")
'''

# #   ii. 对缺失“评论评分”数据项进行均值插补 (fillna函数)
# ##################################################################
# #import pandas as pd #导入模块
# #df = pd.read_excel('titanic3.xls',sheet_name="Sheet1") #加载数据
# #df = pd.read_csv('pp.csv') #加载数据
# print('\n=========替补前=======================')
# print(df)
# print('\n=========填补后原数据=======================')
# # 计算均值
# mean = df['pclass'].mean()
# data = df["pclass"].fillna(mean, inplace=True)
# # 如果inplace=True的话,则是在原始数据集本身进行替换数据,不会生成数据副本
# # data4 = df["pclass"].fillna(df['pclass'].mean(), inplace=True)
# # data5= df['pclass'].fillna(method='ffill') #pad/ffill选择上一个非缺失值
# # data5= df['pclass'].fillna(method='bfill') #backfill/bfill选择下一个非缺失值
# # print(data5)
# print(df)
# print('\n=========填补后副本数据=======================')
# print(data)
# df['pclass']= data  #数据集替换
# print(df)
# print('\n=========结束=======================')
#
# print(df.shape) #行列数目
# print(df.columns) #列名
#
# ########################################################################



# #   iii. 对缺失“评论作者”数据项的那条记录进行删除 (dropna函数)
# #################################################################
# # import pandas as pd #导入模块
# # df = pd.read_excel('titanic3.xls',sheet_name="Sheet1") #加载数据
# # df = pd.read_csv('pp.csv') #加载数据
#
# print('\n=========删除前=======================')
# print(df)
# print(df.shape)
# print('\n=========删除后原数据=======================')
# '''
#  axis=0:0(按列查找行删除)或者1(按行找列删除)
#  subset=["列的名字"]:去重的行/列.默认为None,即所有行/列,array型
#  inplace=True:是否在原表上进行操作.默认为None
#  haw(删除的形式): any:只要有缺失值就进行操作(默认),all:当且仅当全部为缺失值时才执行删除操作
#  '''
# # 如果名字为'pclass'的这一列存在缺失值,则在原始数据集上把存在缺失值的这一行所有数据全部删除
# data = df.dropna(axis=0,subset=['pclass'], how='any',inplace=True)

# print(df)
# print(df.shape)
#
#
# print('\n=========删除后副本数据=======================')
# print(data)
# print(data.shape)
#
#
# print('\n=========结束=======================')
#
# #######################################################################



# # iv.对冗余数据记录进行删除
# # 查找数据集中存在的重复值(duplicated函数)
# # 数据集中删除重复数据(drop_duplicates函数)
# ################################################################
# # import pandas as pd #导入模块
# # df = pd.read_excel('titanic3.xls',sheet_name="Sheet1") #加载数据
# # df = pd.read_csv('pp.csv') #加载数据
# print('\n=========查找数据集中存在的重复值=======================')
# # 数据集中第一个出现的数认定为False,第二个一样的以及第二个以后的认定为True
# print(df.duplicated()) #False当前行不是重复值 ,True当前行为重复值
# print(df.duplicated().sum()) #打印数据集中重复行数目

# print('\n=========去重前=======================')
# print(df)
# print(df.shape)
# print('\n=========去重后原数据=======================')
# data = df.drop_duplicates(inplace=True,keep='first/last')
# print(df)
# print(df.shape)
#
# print('\n=========去重后副本数据=======================')
# print(data)
# print(data.shape)
# print('\n=========结束=======================')
#
# #######################################################################


# # v.把清洗后的数据保存至本地磁盘 “D:\\home\\清洗数据结果\\清洗数据结果.txt” 文件中。
# # 以csv格式的文件进行持久化磁盘(to_csv函数)
# #######################################################################
# import pandas as pd #导入模块
# df = pd.read_excel('titanic3.xls',sheet_name="Sheet1") #加载数据
# # # df = pd.read_csv('pp.csv') #加载数据
# df.to_csv('pp.csv')#以csv格式的文件进行持久化磁盘
#
# # df.to_csv('D:\\home\\清洗数据结果\\清洗数据结果.txt')
# #会在指定路径生成一个名字为titanic3.txt文件或者改后缀名生成csv文件
# #######################################################################


dd = pd.read_csv('(sample)sam_tianchi_mum_baby.csv')
print(dd)
cont = dd['gender'] == 2
print(cont)
index = dd[cont].index
print(index)
dd.drop(labels=index,axis=0,inplace=True)
print(dd['gender'])
dd.to_csv('2.csv',index=False,header=True,mode='w')

# 或:
# dd = pd.read_csv('(sample)sam_tianchi_mum_baby.csv')
# print(dd)
# data = dd['gender']
# pp=[]
# for i in data:
#     if i == 2:
#         y = ''
#         pp.append(y)
#     else:
#         pp.append(i)
# # print(pp)
# dd['gender'] = pp
# print(dd[50:65])
# dd.to_csv('1.csv',index=False,header=True,mode='w')
# dd = pd.read_csv('1.csv')
# print(dd)
# print(dd['gender'].isnull().sum())
# dd.dropna(subset=['gender'],inplace=True)
# print(dd['gender'].isnull().sum())
# dd.to_csv('2.csv',index=False,header=True,mode='w')


'''
df.drop()通过指定标签名称和相应的轴,或直接给定索引或列名称来删除行或列

语法

df.drop(labels = None, axis = 0, 
        index = None, columns = None, 
        level = None, inplace = False, 
        errors = ‘raise’)
参数

1.labels:要删除的列或者行,如果要删除多个,传入列表

2.axis:轴的方向,0为行,1为列,默认为0

3.index:指定的一行或多行

4.columns:指定的一列或多列

5.level:索引层级,将删除此层级

6.inplace:布尔值,是否生效

7.errors:ignore或raise,默认为raise,如果为ignore,则容忍错误,仅删除现有标签



'''