赞
踩
本篇文章出自于《利用Python进行数据分析》示例数据
请结合提供的示例数据,分析代码的功能,并进行数据分析与可视化拓展。本篇文章通过四个例子,通过MoviesLens数据集、美国1880-2010年的婴儿名字、美国农业部视频数据库、2012年联邦选举委员会数据库来进行着重讲解。
GroupLens实验室提供了一些从MoviesLens用户那里收集的20世纪90年代末到21世纪初的电影评分数据的集合。浙西数据提供了电影的评分、流派、年份和观众数据(年龄、邮编、性别、职业)。
MovisLens1M数据集包含6000个用户对4000部电影的100万个评分。数据分布在三个表格之中:分别包含评分、用户信息和电影信息。
(1) 首先载入一些python数据分析的库,并且给予它们简称。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
(2)
unames = ["user_id", "gender", "age", "occupation", "zip"]
users = pd.read_table("datasets/movielens/users.dat", sep="::",
header=None, names=unames, engine="python")
rnames = ["user_id", "movie_id", "rating", "timestamp"]
ratings = pd.read_table("datasets/movielens/ratings.dat", sep="::",
header=None, names=rnames, engine="python")
mnames = ["movie_id", "title", "genres"]
movies = pd.read_table("datasets/movielens/movies.dat", sep="::",
header=None, names=mnames, engine="python")
下面介绍一下pd.read_tablie的用法:
第一个参数是filepath_or_buffer(文件)
一般指读取文件的路径。比如读取csv文件。
第二个参数是sep(分隔符)
指定分隔符。如果不指定参数,默认逗号分隔
第三个参数是 header(表头)
表头即列名,默认第0行数据为表头
第四个参数是names(列名)
用于原始数据无表头,又想设置列名的情况。
第五个参数是engine(引擎)
pandas解析数据时用的引擎。pandas 目前的解析引擎提供两种:c、python,默认为 c,因为 c 引擎解析速度更快,但是特性没有 python 引擎全。如果使用 c 引擎没有的特性时,会自动退化为 python 引擎。
当然,参数不止这些,但需要使用的话可搜索pandas文档。
分析功能:
(3)
users.head(5)
ratings.head(5)
movies.head(5)
ratings
输出结果:
分析功能:
(4)
data = pd.merge(pd.merge(ratings, users), movies)
data
data.iloc[0]
输出结果:
分析功能:
(5)
mean_ratings = data.pivot_table("rating", index="title",
columns="gender", aggfunc="mean")
mean_ratings.head(5)
输出结果:
分析功能:
(6)
ratings_by_title = data.groupby("title").size()
ratings_by_title.head()
active_titles = ratings_by_title.index[ratings_by_title >= 250]
active_titles
输出结果:
分析功能:
(7)
mean_ratings = mean_ratings.loc[active_titles]
mean_ratings
输出结果:
分析功能:
mean_ratings = mean_ratings.rename(index={"Seven Samurai (The Magnificent Seven) (Shichinin no samurai) (1954)":
"Seven Samurai (Shichinin no samurai) (1954)"})
功能分析:
(9)
top_female_ratings = mean_ratings.sort_values("F", ascending=False)
top_female_ratings.head()
输出结果:
分析功能:
(10)
mean_ratings["diff"] = mean_ratings["M"] - mean_ratings["F"]
分析功能:
(11)
sorted_by_diff = mean_ratings.sort_values("diff")
sorted_by_diff.head()
输出结果:
分析功能:
(12)
sorted_by_diff[::-1].head()
输出结果:
分析功能:
(13)
rating_std_by_title = data.groupby("title")["rating"].std()
rating_std_by_title = rating_std_by_title.loc[active_titles]
rating_std_by_title.head()
输出结果:
分析功能:
(14)
rating_std_by_title.sort_values(ascending=False)[:10]
输出结果:
分析功能:
(15)
movies["genres"].head()
movies["genres"].head().str.split("|")
movies["genre"] = movies.pop("genres").str.split("|")
movies.head()
输出结果:
分析功能:
(16)
movies_exploded = movies.explode("genre")
movies_exploded[:10]
输出结果:
分析功能;
(17)
ratings_with_genre = pd.merge(pd.merge(movies_exploded, ratings), users)
ratings_with_genre.iloc[0]
genre_ratings = (ratings_with_genre.groupby(["genre", "age"])
["rating"].mean()
.unstack("age"))
genre_ratings[:10]
输出结果:
分析功能:
美国社会保障局(SSA)提供了从1880年至现在的婴儿姓名频率的数据。可以使用这些数据做很多事情:
根据给定的名字对婴儿名字随时间的比例进行可视化
确定一个名字的相对排位
确定每年最受欢迎的名字,或者流行程度最高或最低的名字
(1)
!head -n 10 datasets/babynames/yob1880.txt
分析功能:
(2)
names1880 = pd.read_csv("datasets/babynames/yob1880.txt",
names=["name", "sex", "births"])
names1880
输出结果:
分析功能:
(3)
names1880.groupby("sex")["births"].sum()
输出结果:
分析功能:
(4)
pieces = []
for year in range(1880, 2011):
path = f"datasets/babynames/yob{year}.txt"
frame = pd.read_csv(path, names=["name", "sex", "births"])
# Add a column for the year
frame["year"] = year
pieces.append(frame)
# Concatenate everything into a single DataFrame
names = pd.concat(pieces, ignore_index=True)
names
输出结果:
分析功能:
(5)
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")
输出结果:
分析功能:
(6)
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
输出结果:
分析功能:
(7)
names.groupby(["year", "sex"])["prop"].sum()
输出结果:
分析功能:
(8)
def get_top1000(group):
return group.sort_values("births", ascending=False)[:1000]
grouped = names.groupby(["year", "sex"])
top1000 = grouped.apply(get_top1000)
top1000.head()
输出结果:
分析功能:
(9)
top1000 = top1000.reset_index(drop=True)
(10)
top1000.head()
输出结果:
分析功能:
(11)
boys = top1000[top1000["sex"] == "M"]
girls = top1000[top1000["sex"] == "F"]
(12)
total_births = top1000.pivot_table("births", index="year",
columns="name",
aggfunc=sum)
(13)
total_births.info()
subset = total_births[["John", "Harry", "Mary", "Marilyn"]]
subset.plot(subplots=True, figsize=(12, 10),
title="Number of births per year")
输出结果:
(14)
plt.figure()
输出结果:
分析功能:
(15)
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))
输出结果:
分析功能:
(16)
df = boys[boys["year"] == 2010]
df
输出结果:
分析功能:
(17)
prop_cumsum = df["prop"].sort_values(ascending=False).cumsum()
prop_cumsum[:10]
prop_cumsum.searchsorted(0.5)
分析功能:
(18)
df = boys[boys.year == 1900]
in1900 = df.sort_values("prop", ascending=False).prop.cumsum()
in1900.searchsorted(0.5) + 1
分析功能:
(19)
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()
(20)
fig = plt.figure()
输出结果:
分析功能:
(21)
diversity.head()
diversity.plot(title="Number of popular names in top 50%")
输出结果:
分析功能:
(22)
def get_last_letter(x):
return x[-1]
last_letters = names["name"].map(get_last_letter)
last_letters.name = "last_letter"
table = names.pivot_table("births", index=last_letters,
columns=["sex", "year"], aggfunc=sum)
分析功能:
(23)
subtable = table.reindex(columns=[1910, 1960, 2010], level="year")
subtable.head()
输出结果:
分析功能:
(24)
subtable.sum()
letter_prop = subtable / subtable.sum()
letter_prop
输出结果:
分析功能:
(25)
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 1, figsize=(10, 8))
letter_prop["M"].plot(kind="bar", rot=0, ax=axes[0], title="Male")
letter_prop["F"].plot(kind="bar", rot=0, ax=axes[1], title="Female",
legend=False)
输出结果:
(26)
plt.subplots_adjust(hspace=0.25)
输出结果:
(27)
letter_prop = table / table.sum()
dny_ts = letter_prop.loc[["d", "n", "y"], "M"].T
dny_ts.head()
输出结果:
(28)
fig = plt.figure()
输出结果:
(29)
dny_ts.plot()
输出结果:
分析功能:
(30)
all_names = pd.Series(top1000["name"].unique())
lesley_like = all_names[all_names.str.contains("Lesl")]
lesley_like
输出结果:
分析功能:
(31)
filtered = top1000[top1000["name"].isin(lesley_like)]
filtered.groupby("name")["births"].sum()
输出结果:
分析功能:
(32)
table = filtered.pivot_table("births", index="year",
columns="sex", aggfunc="sum")
table = table.div(table.sum(axis="columns"), axis="index")
table.tail()
输出结果:
(33)
fig = plt.figure()
输出结果:
(34)
table.plot(style={"M": "k-", "F": "k--"})
输出结果:
美国农业部提供了食物营养信息数据库。每种事务都有一些识别属性以及两份营养元素和营养比例的列表。这种形式的数据不适合分析,所以需要做一些工作将数据转换成更好的形式。
分析功能:
import json
db = json.load(open("datasets/usda_food/database.json"))
len(db)
输出结果:
分析功能:
(2)
db[0].keys()
db[0]["nutrients"][0]
nutrients = pd.DataFrame(db[0]["nutrients"])
nutrients.head(7)
输出结果:
分析功能:
(3)
info_keys = ["description", "group", "id", "manufacturer"]
info = pd.DataFrame(db, columns=info_keys)
info.head()
info.info()
输出结果:
分析功能:
(4)
pd.value_counts(info["group"])[:10]
输出结果:
分析功能:
(5)
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
输出结果:
分析功能:
(6)
nutrients.duplicated().sum() # number of duplicates
nutrients = nutrients.drop_duplicates()
(7)
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)
nutrients
输出结果:
分析功能:
(8)
ndata = pd.merge(nutrients, info, on="id")
ndata.info()
ndata.iloc[30000]
输出结果:
(9)
fig = plt.figure()
输出结果:
分析功能:
(10)
result = ndata.groupby(["nutrient", "fgroup"])["value"].quantile(0.5)
result["Zinc, Zn"].sort_values().plot(kind="barh")
输出结果:
分析功能:
(11)
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"]]
# make the food a little smaller
max_foods["food"] = max_foods["food"].str[:50]
分析功能:
(12)
max_foods.loc["Amino Acids"]["food"]
输出结果:
美国联邦选举委员会公布了有关政治运动贡献的数据。这些数据包括捐赠者姓名、职业和雇主、地址和缴费金额。你可以尝试做一下的分析:
按职业和雇主的捐赠统计
按捐赠金额统计
按州进行统计
(1)
fec = pd.read_csv("datasets/fec/P00000001-ALL.csv", low_memory=False)
fec.info()
输出结果:
分析功能:
(2)
fec.iloc[123456]
输出结果:
分析功能:
(3)
unique_cands = fec["cand_nm"].unique()
unique_cands
unique_cands[2]
输出结果:
分析功能:
(4)
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"}
分析功能:
(5)
fec["cand_nm"][123456:123461]
fec["cand_nm"][123456:123461].map(parties)
# Add it as a column
fec["party"] = fec["cand_nm"].map(parties)
fec["party"].value_counts()
输出结果:
分析功能:
(6)
(fec["contb_receipt_amt"] > 0).value_counts()
输出结果:
分析功能:
(7)
fec = fec[fec["contb_receipt_amt"] > 0]
分析功能:
(8)
fec_mrbo = fec[fec["cand_nm"].isin(["Obama, Barack", "Romney, Mitt"])]
分析功能:
(9)
fec["contbr_occupation"].value_counts()[:10]
输出结果:
分析功能:
(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):
# If no mapping provided, return x
return occ_mapping.get(x, x)
fec["contbr_occupation"] = fec["contbr_occupation"].map(get_occ)
分析功能:
(11)
emp_mapping = {
"INFORMATION REQUESTED PER BEST EFFORTS" : "NOT PROVIDED",
"INFORMATION REQUESTED" : "NOT PROVIDED",
"SELF" : "SELF-EMPLOYED",
"SELF EMPLOYED" : "SELF-EMPLOYED",
}
def get_emp(x):
# If no mapping provided, return x
return emp_mapping.get(x, x)
fec["contbr_employer"] = fec["contbr_employer"].map(get_emp)
分析功能:
(12)
by_occupation = fec.pivot_table("contb_receipt_amt",
index="contbr_occupation",
columns="party", aggfunc="sum")
over_2mm = by_occupation[by_occupation.sum(axis="columns") > 2000000]
over_2mm
输出结果:
分析功能:
(13)
plt.figure()
输出结果:
分析功能:
(14)
over_2mm.plot(kind="barh")
输出结果:
分析功能:
(15)
def get_top_amounts(group, key, n=5):
totals = group.groupby(key)["contb_receipt_amt"].sum()
return totals.nlargest(n)
分析功能:
(16)
grouped = fec_mrbo.groupby("cand_nm")
grouped.apply(get_top_amounts, "contbr_occupation", n=7)
grouped.apply(get_top_amounts, "contbr_employer", n=10)
输出结果:
分析功能:
(17)
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)
labels
输出结果:
分析功能:
(18)
grouped = fec_mrbo.groupby(["cand_nm", labels])
grouped.size().unstack(level=0)
输出结果:
分析功能:
(19)
plt.figure()
输出结果:
分析功能:
(20)
bucket_sums = grouped["contb_receipt_amt"].sum().unstack(level=0)
normed_sums = bucket_sums.div(bucket_sums.sum(axis="columns"),
axis="index")
normed_sums
normed_sums[:-2].plot(kind="barh")
输出结果:
分析功能:
(21)
grouped = fec_mrbo.groupby(["cand_nm", "contbr_st"])
totals = grouped["contb_receipt_amt"].sum().unstack(level=0).fillna(0)
totals = totals[totals.sum(axis="columns") > 100000]
totals.head(10)
输出结果:
分析功能:
(22)
percent = totals.div(totals.sum(axis="columns"), axis="index")
percent.head(10)
输出结果:
分析功能:
不积跬步,无以至千里,不积细流,无以成江海。相信读者通过这片文章后,一定能够熟练掌握如何利用python进行数据分析,相信读者一定能够有所收获,在未来的学习或者工作生活中,能够大展身手!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。