赞
踩
当使用 Pandas 进行数据分析和处理时,你可以利用其强大的功能来加载、处理和分析各种数据集。Pandas 提供了灵活的数据结构和直观的操作方法,使得数据处理变得更加简单和高效。
所有运行结果为代码在jupyter notebook上分步运行截图
目录:
1.美国农业部视频数据库
2.MoviesLens 1M数据集
3.美国1880-2010年的婴儿名字
4.2012年联邦选举委员会数据库
以下是对四个用例的具体分析,希望可以有助你学习数据分析与可视化,祝学习路上,青春有梦,年少有爱。
1.美国农业部视频数据库
美国农业部提供了食物营养信息数据库。每种事务都有一些识别属性以及两份营养元素和营养比例的列表。这种形式的数据不适合分析,所以需要做一些工作将数据转换成更好的形式。
import json
db = json.load(open("datasets/usda_food/database.json"))
len(db)
db[0].keys()
编辑功能:导入 json 库并加载名为 "database.json" 的数据文件。 运行结果:获取了数据集的长度以及每个事务的键。
db[0]["nutrients"][0]
nutrients = pd.DataFrame(db[0]["nutrients"])
nutrients.head(7)
功能:从第一个事务中获取营养元素的信息,并创建一个包含营养元素的数据帧。 运行结果:显示了营养元素数据帧的前7行。
info_keys = ["description", "group", "id", "manufacturer"]
info = pd.DataFrame(db, columns=info_keys)
info.head()
info.info()
编辑功能:基于指定的信息键,创建一个包含事务信息的数据帧。 运行结果:显示了信息数据帧的前几行以及关于数据帧的基本信息。
nutrients = []
for rec in db:
fnuts = pd.DataFrame(rec["nutrients"])
fnuts["id"] = rec["id"]
nutrients.append(fnuts)
nutrients = pd.concat(nutrients, ignore_index=True)
nutrients
编辑功能:将营养元素数据转换为更好的形式,通过迭代事务并将营养元素添加到列表中,并使用 concat 函数将它们合并为一个数据帧。 运行结果:显示了转换后的营养元素数据帧。
nutrients.duplicated().sum()
nutrients = nutrients.drop_duplicates()
编辑功能:查找并删除营养元素数据帧中的重复记录。 运行结果:显示了重复记录的数量,并更新了去重后的营养元素数据帧。
col_mapping = {"description": "food", "group": "fgroup"}
info = info.rename(columns=col_mapping, copy=False)
info.info()
col_mapping = {"description": "nutrient", "group": "nutgroup"}
nutrients = nutrients.rename(columns=col_mapping, copy=False)
编辑功能:重命名信息数据帧和营养元素数据帧的列名,以便更清晰地表示数据。 运行结果:显示了更新后的信息数据帧和营养元素数据帧的基本信息。
ndata = pd.merge(nutrients, info, on="id")
ndata.info()
ndata.iloc[30000]
编辑功能:根据事务的 ID 将信息数据帧和营养元素数据帧合并为一个新的数据帧,并展示特定行的数据。 运行结果:显示了合并后的数据帧的基本信息和特定行的数据。
import matplotlib.pyplot as plt
fig = plt.figure()
result = ndata.groupby(["nutrient", "fgroup"])["value"].quantile(0.5)
result["Zinc, Zn"].sort_values().plot(kind="barh")
编辑功能:使用 matplotlib 库绘制营养元素 "Zinc, Zn" 在不同食物组中的中位数值的水平条形图。 运行结果:显示了条形图。
by_nutrient = ndata.groupby(["nutgroup", "nutrient"])
def get_maximum(x):
return x.loc[x.value.idxmax()]
max_foods = by_nutrient.apply(get_maximum)[["value", "food"]]
max_foods["food"] = max_foods["food"].str[:50]
max_foods.loc["Amino Acids"]["food"]
编辑功能:根据营养元素的类别对数据进行分组,并找到每个类别中具有最大值的食物。同时,限制食物名称的长度。 运行结果:显示了属于 "Amino Acids" 类别的食物的结果。
通过以上分析,我们对提供的示例数据进行了详细的功能解释和运行结果展示。同时,我们进行了数据分析与可视化拓展,涉及到数据清洗、合并、可视化和进一步分析。这些代码示例提供了在实际数据分析中使用 Pandas 和 Matplotlib 进行数据处理和可视化的一般方法。你可以根据自己的需求和数据集进一步拓展和探索数据。
2.美国1880-2010年的婴儿名字
美国社会保障局(SSA)提供了从1880年至现在的婴儿姓名频率的数据。可以使用这些数据做很多事情:
根据给定的名字对婴儿名字随时间的比例进行可视化
确定一个名字的相对排位
确定每年最受欢迎的名字,或者流行程度最高或最低的名字
源代码:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
# 读取1880年的数据
names1880 = pd.read_csv("datasets/babynames/yob1880.txt", names=["name", "sex", "births"])
names1880
# 按性别分组并计算总出生人数
names1880.groupby("sex")["births"].sum()
# 读取所有年份的数据并添加年份列
pieces = []
for year in range(1880, 2011):
path = f"datasets/babynames/yob{year}.txt"
frame = pd.read_csv(path, names=["name", "sex", "births"])
frame["year"] = year
pieces.append(frame)
# 将所有数据合并为一个DataFrame
names = pd.concat(pieces, ignore_index=True)
names
# 计算每年每个性别的总出生人数
total_births = names.pivot_table("births", index="year", columns="sex", aggfunc=sum)
total_births.tail()
# 绘制每年每个性别的总出生人数图表
total_births.plot(title="Total births by sex and year")
# 计算每个名字在其出生年份的比例
def add_prop(group):
group["prop"] = group["births"] / group["births"].sum()
return group
names = names.groupby(["year", "sex"], group_keys=False).apply(add_prop)
names
# 检查每年每个性别的比例之和是否为1
names.groupby(["year", "sex"])["prop"].sum()
# 获取每年每个性别出生人数最高的前1000个名字
def get_top1000(group):
return group.sort_values("births", ascending=False)[:1000]
grouped = names.groupby(["year", "sex"])
top1000 = grouped.apply(get_top1000)
top1000.head()
# 重置索引并获取前1000个名字的数据
top1000 = top1000.reset_index(drop=True)
top1000.head()
# 分离男孩和女孩的数据
boys = top1000[top1000["sex"] == "M"]
girls = top1000[top1000["sex"] == "F"]
# 计算每年每个名字的总出生人数
total_births = top1000.pivot_table("births", index="year", columns="name", aggfunc=sum)
total_births.info()
# 选取特定名字的数据并绘制子图
subset = total_births[["John", "Harry", "Mary", "Marilyn"]]
subset.plot(subplots=True, figsize=(12, 10), title="Number of births per year")
# 绘制比例图
plt.figure()
table = top1000.pivot_table("prop", index="year", columns="sex", aggfunc=sum)
table.plot(title="Sum of table1000.prop by year and sex", yticks=np.linspace(0, 1.2, 13))
# 获取2010年男孩名字的数据
df = boys[boys["year"] == 2010]
df
# 计算比例的累积和,并返回前10个值
prop_cumsum = df["prop"].sort_values(ascending=False).cumsum()
prop_cumsum[:10]
# 查找比例累积和超过0.5的位置
prop_cumsum.searchsorted(0.5)
# 获取1900年男孩名字的数据
df = boys[boys["year"] == 1900]
df
# 计算1900年名字的累积和,并返回超过0.5的位置
in1900 = df.sort_values("prop", ascending=False).prop.cumsum()
in1900.searchsorted(0.5) + 1
# 计算在每年每个性别中占比超过50%的名字数量
def get_quantile_count(group, q=0.5):
group = group.sort_values("prop", ascending=False)
return group.prop.cumsum().searchsorted(q) + 1
diversity = top1000.groupby(["year", "sex"]).apply(get_quantile_count)
diversity = diversity.unstack()
diversity.head()
# 绘制每年性别中热门名字的数量图表
fig = plt.figure()
diversity.plot(title="Number of popular names in top 50%")
# 获取名字的最后一个字母
def get_last_letter(x):
return x[-1]
last_letters = names["name"].map(get_last_letter)
last_letters.name = "last
分步运行及解释:
3.2012年联邦选举委员会数据库
美国联邦选举委员会公布了有关政治运动贡献的数据。这些数据包括捐赠者姓名、职业和雇主、地址和缴费金额。你可以尝试做一下的分析:
按职业和雇主的捐赠统计
按捐赠金额统计
按州进行统计
# 使用read_csv方法读取CSV文件,设置low_memory为False以提高性能
fec = pd.read_csv("datasets/fec/P00000001-ALL.csv", low_memory=False)
# 查看数据信息
fec.info()
# 输出数据中的第123456行
fec.iloc[123456]
# 获取候选人姓名的唯一值
unique_cands = fec["cand_nm"].unique()
unique_cands
# 获取唯一值中的第2个元素
unique_cands[2]
# 创建一个包含候选人和所属政党的字典
parties = {"Bachmann, Michelle": "Republican",
"Cain, Herman": "Republican",
"Gingrich, Newt": "Republican",
"Huntsman, Jon": "Republican",
"Johnson, Gary Earl": "Republican",
"McCotter, Thaddeus G": "Republican",
"Obama, Barack": "Democrat",
"Paul, Ron": "Republican",
"Pawlenty, Timothy": "Republican",
"Perry, Rick": "Republican",
"Roemer, Charles E. 'Buddy' III": "Republican",
"Romney, Mitt": "Republican",
"Santorum, Rick": "Republican"}
# 输出数据中第123456到123460行的候选人姓名
fec["cand_nm"][123456:123461]
# 使用parties字典将候选人姓名映射为所属政党
fec["cand_nm"][123456:123461].map(parties)
# 将所属政党作为一列添加到数据中
fec["party"] = fec["cand_nm"].map(parties)
# 统计每个政党的捐款次数
fec["party"].value_counts()
# 筛选出捐款金额大于0的数据
fec = fec[fec["contb_receipt_amt"] > 0]
# 筛选出候选人为"Obama, Barack"或"Romney, Mitt"的数据
fec_mrbo = fec[fec["cand_nm"].isin(["Obama, Barack", "Romney, Mitt"])]
# 统计不同职业的捐款次数
fec["contbr_occupation"].value_counts()[:10]
# 创建一个职业映射字典
occ_mapping = {
"INFORMATION REQUESTED PER BEST EFFORTS": "NOT PROVIDED",
"INFORMATION REQUESTED": "NOT PROVIDED",
"INFORMATION REQUESTED (BEST EFFORTS)": "NOT PROVIDED",
"C.E.O.": "CEO"
}
def get_occ(x):
# 如果存在映射关系,则返回映射结果;否则返回原值
return occ_mapping.get(x, x)
# 使用map函数将职业(contbr_occupation)映射为指定的值
fec["contbr_occupation"] = fec["contbr_occupation"].map(get_occ)
# 创建一个雇主映射字典
emp_mapping = {
"INFORMATION REQUESTED PER BEST EFFORTS": "NOT PROVIDED",
"INFORMATION REQUESTED": "NOT PROVIDED",
"SELF": "SELF-EMPLOYED",
"SELF EMPLOYED": "SELF-EMPLOYED",
}
def get_emp(x):
# 如果存在映射关系,则返回映射结果;否则返回原值
return emp_mapping.get(x, x)
# 使用map函数将雇主(contbr_employer)映射为指定的值
fec["contbr_employer"] = fec["contbr_employer"].map(get_emp)
# 使用pivot_table函数创建一个按职业和政党划分的透视表
by_occupation = fec.pivot_table("contb_receipt_amt", index="contbr_occupation", columns="party", aggfunc="sum")
# 筛选出总捐款金额大于2000000的职业
over_2mm = by_occupation[by_occupation.sum(axis="columns") > 2000000]
# 输出结果
over_2mm
# 绘制水平条形图
plt.figure()
over_2mm.plot(kind="barh")
# 定义一个函数,用于获取分组中捐款金额最多的前n个值
def get_top_amounts(group, key, n=5):
# 对分组后的数据按指定的键进行分组求和
totals = group.groupby(key)["contb_receipt_amt"].sum()
# 获取前n个最大值
return totals.nlargest(n)
grouped = fec_mrbo.groupby("cand_nm")
# 对每个候选人分组,分别调用get_top_amounts函数,传入不同的键和n值
occupation_top = grouped.apply(get_top_amounts, "contbr_occupation", n=7)
employer_top = grouped.apply(get_top_amounts, "contbr_employer", n=10)
bins = np.array([0, 1, 10, 100, 1000, 10000, 100_000, 1_000_000, 10_000_000])
labels = pd.cut(fec_mrbo["contb_receipt_amt"], bins)
labelsgrouped = fec_mrbo.groupby(["cand_nm", labels])
grouped.size().unstack(level=0)
plt.figure()
# 计算每个组的金额总和,并将结果转换成二维表格形式
bucket_sums = grouped["contb_receipt_amt"].sum().unstack(level=0)
# 计算每个组的金额总和占总体金额总和的比例
normed_sums = bucket_sums.div(bucket_sums.sum(axis="columns"), axis="index")
# 绘制水平条形图
normed_sums[:-2].plot(kind="barh")
plt.ylabel("Donation Amount Range")
plt.xlabel("Normalized Percentage")
plt.title("Normalized Percentage of Donation Amount Range by Candidate")
plt.show()
# 根据候选人和捐款人所在州进行分组
grouped = fec_mrbo.groupby(["cand_nm", "contbr_st"])
# 计算每个组的捐款总额,并将结果转换成二维表格形式
totals = grouped["contb_receipt_amt"].sum().unstack(level=0).fillna(0)
# 过滤掉总捐款额小于100000的组
totals = totals[totals.sum(axis="columns") > 100000]
# 显示前10个组的结果
totals.head(10)
# 计算每个组的捐款金额占总捐款额的比例
percent = totals.div(totals.sum(axis="columns"), axis="index")
# 显示前10个组的结果
percent.head(10)
、
2.MoviesLens 1M数据集
GroupLens实验室提供了一些从MoviesLens用户那里收集的20世纪90年代末到21世纪初的电影评分数据的集合。浙西额数据提供了电影的评分、流派、年份和观众数据(年龄、邮编、性别、职业)。 MovisLens1M数据集包含6000个用户对4000部电影的100万个评分。数据分布在三个表格之中:分别包含评分、用户信息和电影信息。
import pandas as pd
# 定义用户信息的列名
unames = ["user_id", "gender", "age", "occupation", "zip"]
# 读取用户信息文件为DataFrame
users = pd.read_table("datasets/movielens/users.dat", sep="::",
header=None, names=unames, engine="python")
# 定义评分信息的列名
rnames = ["user_id", "movie_id", "rating", "timestamp"]
# 读取评分信息文件为DataFrame
ratings = pd.read_table("datasets/movielens/ratings.dat", sep="::",
header=None, names=rnames, engine="python")
# 定义电影信息的列名
mnames = ["movie_id", "title", "genres"]
# 读取电影信息文件为DataFrame
movies = pd.read_table("datasets/movielens/movies.dat", sep="::",
header=None, names=mnames, engine="python")
# 输出users的前5行数据
users.head(5)
# 输出ratings的前5行数据
ratings.head(5)
# 输出movies的前5行数据
movies.head(5)
# 将ratings、users和movies三个DataFrame合并为一个DataFrame
ratingsdata = pd.merge(pd.merge(ratings, users), movies)
# 输出data,这里应为ratingsdata的一个拼写错误
data
# 输出ratingsdata的第一行数据
data.iloc[0]
# 根据电影标题和性别计算评分的平均值,并存储在mean_ratings中
mean_ratings = data.pivot_table("rating", index="title",
columns="gender", aggfunc="mean")
# 输出mean_ratings的前5行数据
mean_ratings.head(5)
# 统计每部电影的评分数量
ratings_by_title = data.groupby("title").size()
# 输出ratings_by_title的前5行数据
ratings_by_title.head()
# 筛选出评分数量大于等于250的活跃电影标题
active_titles = ratings_by_title.index[ratings_by_title >= 250]
# 在mean_ratings中筛选出活跃电影的平均评分数据
active_titlesmean_ratings = mean_ratings.loc[active_titles]
# 将mean_ratings重命名为"Seven Samurai (Shichinin no samurai) (1954)"的行
mean_ratingsmean_ratings = mean_ratings.rename(index={"Seven Samurai (The Magnificent Seven) (Shichinin no samurai) (1954)":
"Seven Samurai (Shichinin no samurai) (1954)"})
# 根据女性评分对mean_ratings进行降序排序
top_female_ratings = mean_ratings.sort_values("F", ascending=False)
# 输出top_female_ratings的前5行数据
top_female_ratings.head()
# 计算男性评分和女性评分之间的差异并添加为新列
mean_ratings["diff"] = mean_ratings["M"] - mean_ratings["F"]
# 根据差异列对mean_ratings进行排序
sorted_by_diff = mean_ratings.sort_values("diff")
# 输出差异列按降序排列的前5行数据
sorted_by_diff.head()
# 输出差异列按升序排列的前5行数据
sorted_by_diff[::-1].head()
# 统计每部电影的评分标准差
rating_std_by_title = data.groupby("title")["rating"].std()
# 在活跃电影中筛选出评分标准差数据
rating_std_by_title = rating_std_by_title.loc[active_titles]
# 输出评分标准差最大的前10部电影
rating_std_by_title.sort_values(ascending=False)[:10]
# 输出movies的前5行类型数据
movies["genres"].head()
# 将电影的类型按分隔符进行分割
movies["genres"].head().str.split("|")
# 将分割后的类型列表存储为movies的新列genre
movies["genre"] = movies.pop("genres").str.split("|")
# 输出movies的前5行数据
movies.head()
# 将movies的genre列拆分为多行
movies_exploded = movies.explode("genre")
# 输出拆分后的movies_exploded的前10行数据
movies_exploded[:10]
# 将movies_exploded、ratings和users三个DataFrame合并为一个DataFrame
ratings_with_genre = pd.merge(pd.merge(movies_exploded, ratings), users)
# 输出ratings_with_genre的第一行数据
ratings_with_genre.iloc[0]
# 根据类型和年龄段对评分进行分组,并计算平均值
genre_ratings = (ratings_with_genre.groupby(["genre", "age"])
["rating"].mean()
.unstack("age"))
# 输出genre_ratings的前10行数据
genre_ratings[:10]
根据代码的功能,你可以进行以下的数据分析和可视化拓展:
这些拓展可以帮助你深入理解数据集的特征,并从不同角度进行分析和可视化展示。根据具体需求,你还可以进一步拓展代码和应用其他数据分析方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。