本文概述
- pandas数据探索
- Groupbys和split-apply-combine回答问题
- 日常使用中的Groupbys和split-app-combine
文章图片
Netflix最近发布了一些用户评分数据。我想问一个简单的问题:Netflix订户更喜欢旧电影还是新电影?
直观地讲, 你希望将数据集分成几组, 每年一组, 然后计算一个汇总统计量, 例如平均值或中位数, 然后查看该统计量是否随着时间的推移而增加(此后, 你可能想要进行统计检验)。
很棒的是, 存在一个用于执行和考虑此操作的概念框架, 以及Python和R中的实现。该框架被称为” split-apply-combine” , 因为我们…
- 步骤1:通过从原始DataFrame创建groupby对象将数据分为几组;
- 步骤2:应用一个函数, 在这种情况下, 应用一个聚合函数来计算摘要统计信息(你也可以在此步骤中转换或过滤数据);
- 步骤3:将结果合并到一个新的DataFrame中。 :target:before { content:"
"
;
display:block;
height:150px;
margin:-150px 0 0;
} h3 {font-weight:normal;
margin-top:.5em} h4 { font-weight:lighter }
如果你发现这项技术很有用, 则可以(在许多其他事情中)进一步了解它, 并在我们的” 用pandas操作数据帧” 课程中进行实践。
pandas数据探索 汇入资料
在这里, 你将使用pandas, groupby对象和split-apply-combine的原理来检查Netflix电影范围根据发行年份的不同而变化。我最初是在这里遇到data.world上的数据的, 你也可以在这里在概念中心找到它。如果你想重现它, 可以在这里找到这篇文章中的所有代码。
你将首先导入必要的包和数据, 并检出数据的前五行:
# Import packages and set visualization style
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
%matplotlib inline
# Import data and check out head of DataFrame
df = pd.read_csv('data/chasewillden-netflix-shows/data/netflix.csv')
df.head()
标题 | 评分 | 等级 | 评级说明 | release_year | user_rating_score | user_rating_size | |
---|---|---|---|---|---|---|---|
0 | 白小鸡 | PG-13 | 粗俗和性幽默, 语言和一些毒品… | 80 | 2004 | 82.0 | 80 |
1 | 幸运数字Slevin | [R | 强烈的暴力, 性内容和成人语言… | 100 | 2006 | NaN | 82 |
2 | 实习医生格蕾 | TV-14 | 父母强烈警告。可能不合适… | 90 | 2016 | 98.0 | 80 |
3 | 越狱 | TV-14 | 父母强烈警告。可能不合适… | 90 | 2008 | 98.0 | 80 |
4 | 老爸老妈的浪漫史 | 电视PG | 建议家长指导。可能不适合… | 70 | 2014 | 94.0 | 80 |
用图和统计汇总数据
pandasDataFrame .info()方法是无价的。在下面应用它显示你有1000行和7列数据, 而且感兴趣的列user_rating_score只有605个非空值。这意味着有395个缺失值:
# Check out info of DataFrame
df.info()
<
class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 7 columns):
title1000 non-null object
rating1000 non-null object
ratinglevel941 non-null object
ratingdescription1000 non-null int64
release_year1000 non-null int64
user_rating_score605 non-null float64
user_rating_size1000 non-null int64
dtypes: float64(1), int64(3), object(3)
memory usage: 54.8+ KB
你可以删除具有任何缺失值的行, 删除任何重复的行并使用seaborn构建DataFrame的成对图, 以便获得数据的视觉感。你将通过” 评分” 列为数据着色。查看这些图, 看看可以从中获得什么信息。
# Drop rows with missing values and drop duplicate
df.dropna(inplace=True)
df.drop_duplicates(inplace=True)# Visualize pairplot of df
sns.pairplot(df, hue='rating');
文章图片
签出例如user_rating_score作为release_year的函数。没有视觉上可识别的趋势, 但是也许某些数据分析将得出任何趋势。如果你想查看DataFrame的几个摘要统计信息, 也可以使用.describe()方法执行此操作:
# Get summary stats of df
df.describe()
评级说明 | release_year | user_rating_score | user_rating_size | |
---|---|---|---|---|
计数 | 246.000000 | 246.000000 | 246.000000 | 246.0 |
意思 | 73.556911 | 2010.272358 | 81.390244 | 80.0 |
小时 | 26.616145 | 8.887219 | 12.677883 | 0.0 |
我 | 10.000000 | 1940.000000 | 55.000000 | 80.0 |
25% | 60.000000 | 2007.000000 | 71.000000 | 80.0 |
50% | 80.000000 | 2015.000000 | 83.500000 | 80.0 |
75% | 90.000000 | 2016.000000 | 92.750000 | 80.0 |
最大值 | 124.000000 | 2017.000000 | 99.000000 | 80.0 |
既然你已经签出了数据, 那么现在该是有趣的部分了。首先, 你将使用groupby方法将数据分成几组, 其中每一组都是给定年份发行的电影。这是split-apply-combine中的拆分:
# Group by year
df_by_year = df.groupby('release_year')
这将创建一个groupby对象:
# Check type of GroupBy object
type(df_by_year)
pandas.core.groupby.DataFrameGroupBy
步骤2.申请
这样的分组对象非常有用。还记得DataFrame的.describe()方法返回数字列的摘要统计信息吗?好了, DataFrameGroupBy对象的.describe()方法返回每个数字列的摘要统计信息, 但为拆分中的每个组计算摘要统计信息。就你而言, 适用于每个release_year。这是split-apply-combine中的apply的示例:你将.describe()方法应用于groupby中的每个组。这样做并打印结果的前5行:
# Summary stats over years
df_by_year.describe().head()
评级说明 | user_rating_score | user_rating_size | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
计数 | 意思 | 小时 | 我 | 25% | 50% | 75% | 最大值 | 计数 | 意思 | … | 75% | 最大值 | 计数 | 意思 | 小时 | 我 | 25% | 50% | 75% | 最大值 | |
release_year | |||||||||||||||||||||
1940 | 1.0 | 35.0 | NaN | 35.0 | 35.0 | 35.0 | 35.0 | 35.0 | 1.0 | 61.0 | … | 61.0 | 61.0 | 1.0 | 80.0 | NaN | 80.0 | 80.0 | 80.0 | 80.0 | 80.0 |
1978 | 1.0 | 60.0 | NaN | 60.0 | 60.0 | 60.0 | 60.0 | 60.0 | 1.0 | 86.0 | … | 86.0 | 86.0 | 1.0 | 80.0 | NaN | 80.0 | 80.0 | 80.0 | 80.0 | 80.0 |
1982 | 1.0 | 60.0 | NaN | 60.0 | 60.0 | 60.0 | 60.0 | 60.0 | 1.0 | 68.0 | … | 68.0 | 68.0 | 1.0 | 80.0 | NaN | 80.0 | 80.0 | 80.0 | 80.0 | 80.0 |
1986 | 1.0 | 35.0 | NaN | 35.0 | 35.0 | 35.0 | 35.0 | 35.0 | 1.0 | 67.0 | … | 67.0 | 67.0 | 1.0 | 80.0 | NaN | 80.0 | 80.0 | 80.0 | 80.0 | 80.0 |
1987 | 1.0 | 60.0 | NaN | 60.0 | 60.0 | 60.0 | 60.0 | 60.0 | 1.0 | 58.0 | … | 58.0 | 58.0 | 1.0 | 80.0 | NaN | 80.0 | 80.0 | 80.0 | 80.0 | 80.0 |
如果要查看分组的外观, 可以将groupby对象传递给函数list():
# Cast grouping as a list and check out one year
list(df_by_year)[10]
(1995, title ratingratinglevel\
766BaltoGGeneral Audiences. Suitable for all ages.
967HeavyweightsPGsome rude language and pranksratingdescriptionrelease_yearuser_rating_scoreuser_rating_size
76635199564.080
96760199574.080)
步骤3.合并
【Groupby,拆分应用合并和pandas】假设你想要每年的平均值或中位数user_rating_score。然后, 你可以将.mean()或.median()方法分别应用于groupby对象, 并将它们” 组合” 到新的DataFrame中。
# Get median values by year and print first 5 rows
df_med_by_year = df_by_year.median()
df_med_by_year.head()
评级说明 | user_rating_score | user_rating_size | |
---|---|---|---|
release_year | |||
1940 | 35.0 | 61.0 | 80.0 |
1978 | 60.0 | 86.0 | 80.0 |
1982 | 60.0 | 68.0 | 80.0 |
1986 | 35.0 | 67.0 | 80.0 |
1987 | 60.0 | 58.0 | 80.0 |
# Print index of df
print(df.index)
Int64Index([0, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
908, 911, 917, 931, 962, 966, 967, 972, 973, 979], dtype='int64', length=246)
该索引由原始行号组成, 并用整数标记。当你在上方放置一些行时, 缺少” 1″ 。 df_med_by_year的索引由你分组的原始列中的值组成, 即release_year以来的年份:
# Print index
print(df_med_by_year.index)
Int64Index([1940, 1978, 1982, 1986, 1987, 1989, 1990, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017], dtype='int64', name='release_year')
你对user_rating_score列感兴趣, 该列包含每年的平均评分。你可以切出df_med_by_year的user_rating_score列, 并将其绘制为年份的函数(由DataFrame df_rat_by_year的索引给出):
# Slice out user rating and plot
df_rat_by_year = df_med_by_year['user_rating_score']
plt.scatter(df_rat_by_year.index, df_rat_by_year)
plt.xlabel('year of release')
plt.ylabel('median rating');
文章图片
从图中可以看出, 中位数评分肯定会随着时间的推移而增加。你需要利用一些更复杂的统计数据来使我总体上相信这种趋势, 但是” 探索性数据分析” 示例是进一步研究的一个很好的起点。
日常使用Groupbys和split-app-combine Groupby对象不直观。但是, 它们确实对应于将数据集相对于其一列(或多于一列)进行拆分的自然行为, 但让我们将其保存在另一篇关于按多列和层次结构索引进行分组的文章中。
拆分应用合并原则不仅优雅实用, 而且数据科学家每天都会使用它, 就像上面的示例一样。要了解其更多用途, 请查看Hadley Wickham的原始论文《数据分析的拆分应用组合策略》。如果你有任何想法, 回应和/或反省, 请随时通过twitter @ hugobowne与我联系。
推荐阅读
- R入门教程(管道)
- PEP-8教程(Python中的代码标准)
- Mybatis Generator 生成的mapper只有insert方法
- CodeForces 593D Happy Tree Party [LCA+并查集]
- 2Android-UI(自定义控件&ListView)
- 谷歌商店上架APP被拒绝
- 开发框架-APP(Hybird App)
- 操作系统(Android(Google公司开发的操作系统))
- Create and test an approval workflow with Microsoft Flow