【Pandas】Python数据分析活用Pandas库学习笔记(三)

引言

笔者Python数据分析活用Pandas库学习笔记专栏链接🔗导航:

  1. 【Pandas】Python数据分析活用Pandas库学习笔记(一)
  2. 【Pandas】Python数据分析活用Pandas库学习笔记(二)

第4章 数据组合

数据组合主要包括,连接和合并
连接:添加行,添加列
合并多个数据集:一对一合并;多对一合并;多对多合并

"""
2021.02.21
author:alian
数据组合
"""
import pandas as pd


# 先加载几个数据集
df1 = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\concat_1.csv')
df2 = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\concat_2.csv')
df3 = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\concat_3.csv')

# 添加行
row_concat = pd.concat([df1,df2,df3],ignore_index=True)
print(row_concat)

# 添加列
col_concat = pd.concat([df1,df2,df3],axis=1,ignore_index=True)
col_concat['new_col_list'] = ['n1','n2','n3','n4']  # 添加一个新列
col_concat['new_col_list'] = pd.Series['n1','n2','n3','n4']  # 添加一个新列

# 连接具有不同列的行
rows = pd.concat([df1,df2],ignore_index=False,join='inner')  # join='inner':保留数据集都有的列
# 连接具有不同行的列
cols = pd.concat([df1,df3],axis=1,join='inner')

# 合并多个数据集
person = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\survey_person.csv')
site= pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\survey_site.csv')
survey= pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\survey_survey.csv')
visited= pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\survey_visited.csv')
# 1)一对一合并
visited_subset = visited.loc[[0,2,6],]  # 连接的列不含任何重复值
o2o_merge = site.merge(visited_subset,left_on='name',right_on='site')  # left_on,right_on:指定左右数据集匹配的列
# 2)多对一合并
m2o_merge = site.merge(visited,left_on='name',right_on='site')  # 以“多”数据集为基准自动复制与之匹配
# 3)多对多合并
# 创建多数据集
ps = person.merge(survey,left_on='ident',right_on='person')
vs = visited.merge(survey,left_on='ident',right_on='taken')

ps_vs = ps.merge(vs,left_on=['ident','taken','quant','reading'],
                 right_on=['person','ident','quant','reading'])  # 匹配列一一对应,若名称存在冲突,pandas会自动添加后缀

第5章 缺失数据

在pandas中NaN表示缺失值,缺失值和其他类型的数据不同,实际上它们没有什么意义,缺失值不等于任何值,甚至不等于缺失值。
从numpy库中导入缺失值:

from numpy import NAN,NaN,nan

5.1 判断缺失值

"""
2021.02.21
author:alian
缺失数据
"""
from numpy import NAN,NaN,nan
import pandas as pd

# 测试是否为缺失值的函数:isnull,notnull
print(pd.isnull(NaN))
print(pd.notnull(NaN))

5.2 加载数据中的缺失值

visited_file = r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\survey_visited.csv'
# 直接加载数据
print(pd.read_csv(visited_file))
# 加载数据,不包含默认缺失值
print(pd.read_csv(visited_file,keep_default_na=False))
# 手动指定缺失值
print(pd.read_csv(visited_file,na_values=[''],keep_default_na=False))

5.3 重建索引

# 重建索引
gapminder = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\gapminder.tsv')
life_exp = gapminder.groupby(['year'])['life'].mean()  # 通过分组操作重建索引
print(life_exp)
print(life_exp.loc[range(2000,2010), ])
y2000 = life_exp[life_exp.index>2000]  # 取子集
# 调用reindex方法
print(y2000.reindex(range(2000,2010)))

5.4 处理缺失数据

5.4.1 清理缺失数据

方法一

缺失值数量等于数据总行数减去非缺失值的行数

# 查找缺失值
ebola = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\country_timeseries.csv')
# 统计非缺失值的个数
print(ebola.count())
# 用总行数减去非缺失值的行数即得到缺失值的行数
num_rows = ebola.shape[0]
num_missing = num_rows - ebola.count()
方法二

利用numpy中的count_nonzero和isnull方法统计数据中缺失值的总数或者特定列中缺失值的个数

import numpy as np
print(np.count_nonzero(ebola.isnull()))
print(np.count_nonzero(ebola['Cases_Guinea'].isnull()))
方法三

利用Serise的value_counts方法获取缺失值的个数,dropan参数

print(ebola.Cases_Guinea.value_counts(dropna=False).head())

5.4.2 清除缺失数据

替换
# 替换
print(ebola.fillna(0).iloc[0:10,0:5])  # 用0替换缺失值
前值和后值填充
# 前后值填充
print(ebola.fillna(method='ffill').iloc[0:10,0:5])
print(ebola.fillna(method='bfill').iloc[,0:5].tail())

该方法存在一个问题,若缺失值位于最前或最后那么缺失值将继续存在。

插值

pandas中插值的方法默认以线性插值来填充

print(ebola.interpolate().iloc[0:10,0:5])
删除缺失值

dropna方法删除缺失值:参数how参数指定行或列的删除条件,两种取值,any(只要包含NA值即删除)与all(全为NA才 删除);thresh参数允许在删除行或列之前 指定非NaN值的数量。

忽略缺失值计算

可以忽略缺失值的内置方法有mean和sum,这些参数通常有skipna参数

# 忽略缺失值的计算
print(ebola.Cases_Guinea.sum(skipna=True))

第6章 整理数据

数据整理是指对数据集进行结构化处理,使其易于分析和可视化。它是数据清理的主要目标。整洁数据有助于简化数据分析、可视化和收集工作。
Hadley Wickham指出整洁数据要满足一下3个条件:
每个观测值成一行;每个变量成一列;每种观测单元构成一张表格。

6.1 针对包含值而非变量的列

6.1.1 固定一列

melt函数可以把DataFrame重塑成整洁的数据格式,参数如下:

  • id_vars:该参数是一个容器(列表、元组或ndarray),所表示的变量会保持原样。
  • value_vars:指定想“融合”(或转换为行)的列。它默认会“融合”未在in_vars参数中指定的所有列。
  • var_name:该字符串用于指定value_vars融合后的新列名
  • value_name:该字符串为新列明,代表var_name的值
# 固定一列
pew = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\pew.csv')
pew_long = pd.melt(pew,id_vars='religion',var_name='income',value_name='count')
print(pew_long)

6.1.2 固定多列

# 固定多列
billboard = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\billboard.csv')
billboard_long = pd.melt(billboard,id_vars=['year','artist','track','time','date.entered'],var_name='week',value_name='rating')
print(billboard_long.head())

6.2 包含多个变量的列

6.2.1 单独拆分和添加列(简单方法)

# 包含多个变量的列
ebola = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\country_timeseries.csv')
ebola_long = pd.melt(ebola,id_vars=['Date','Day'])
# 单独拆分和添加列(简单方法)
# 获取variable列,访问字符串方法,依据分隔符拆分列
variable_split = ebola_long.variable.str.split('_')
# 把列拆分好之后,拆分结果会保存在一个列表中。

6.2.2 在单步骤中进行拆分和组合(简单方法)

返回的向量的顺序和数据顺序相同

# 在单个步骤中进行拆分和组合(简单方法)
variable_split = ebola_long.variable.str.split('_',expand = True)
variable_split.columns = ['status','country']
ebola_parsed = pd.concat([ebola_long,variable_split],axis=1)
print(ebola_parsed.head())

6.2.3 在单步骤中进行拆分和组合(复杂方法)

拆分返回的是包含两个元素的列表,且每个元素都是新列。利用这一点,可以使用内置zip函数把拆分项列表组合在一起。
zip的功能可以理解为:把每个传入的容器堆叠起来,然后以元组的形式逐列返回值。
同样可以使用ebola_long.variable.str.split(‘_’)。不过由于容器是Seriies对象,需要将其拆包,可以使用星号操作符*对容器进行拆包。

# 在单步骤中进行拆分和组合(复杂方法)
ebola_long['status'],ebola_long['country'] = zip(*ebola_long.variable.str.split('_'))

6.3 行与列中的变量

# 列与列中的变量
weather = pd.read_csv(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\weather.csv')
weather_melt = pd.melt(weather,id_vars=['id','year','month','element'],var_name='day',value_name='temp')
weather_tidy = weather_melt.pivot_table(index=['id','year','month','day'],columns='element',values='temp')
weather_tidy_flat = weather_tidy.reset_index()

6.4 一张表中多个观测单元(归一化)

# 一张表中多个观测单元(归一化)
billboard_songs = billboard_long[['year','artist','track','time']]
billboard_songs  = billboard_songs.drop_duplicates()  # 删除重复的行
billboard_songs['id'] = range(len(billboard_songs))  # 为每行分配唯一的值
billboard_ratings = billboard_long.merge(billboard_songs,on=['year','artist','track','time'])  # 使用新id匹配歌曲的每周排名
billboard_ratings = billboard_ratings[['id','date.entered','week','rating']]  # 取想放入的列子集

6.5 跨多表的观测单元

# 跨多表的观测单元
import os
import urllib

# 只下载前5个数据集
with open(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\raw_data_urls.txt') as data_urls:
    for line,url in enumerate(data_urls):
        if line ==5:
            break
        fn = url.split('/')[-1].split()
        fp = os.path.join('..','data',fn)
        print(url)
        print(fp)
        urllib.request.urlretrieve(url,fp)
import glob
# 从nyc-taxi数据文件夹获得csv文件列表
nyc_taxi_data = glob.glob(r'D:\Python数据分析\Pandas\pandas_for_everyone-master\data\fhv_*')
# 连接dataframe
taxi1 = pd.read_csv(nyc_taxi_data[0])
taxi2 = pd.read_csv(nyc_taxi_data[1])
taxi3 = pd.read_csv(nyc_taxi_data[2])
taxi4 = pd.read_csv(nyc_taxi_data[3])
taxi5 = pd.read_csv(nyc_taxi_data[4])
taxi = pd.concat([taxi1,taxi2,taxi3,taxi4,taxi5])

6.5.1 使用循环加载多个文件

# 使用循环加载多个文件
list_taxi_df = []
# 循环遍历每个CSV文件名
for csv_filename in nyc_taxi_data:
    # 可以选择输出文件名以便调试
    df = pd.read_csv(csv_filename)
    list_taxi_df.append(df)
# 连接起来
taxi_loop_concat = pd.concat(list_taxi_df)

6.5.2 使用列表推导加载多个文件

# 使用列表推导加载多个文件
list_taxi_df = []
for csv_filename in nyc_taxi_data:
    df = pd.read_csv(csv_filename)
    list_taxi_df.append(df)
# 使用列表推导式重写
list_taxi_df_comp = [pd.read_csv(data) for data in nyc_taxi_data]
# 将结果连接
list_taxi_concat_comp = pd.concat(list_taxi_df_comp)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值