查看原文
其他

数据城堡参赛代码实战篇(三)---我们来探究一个深奥的问题!

文文 Python爱好者社区 2019-04-07

作者:文文

个人公众号:小小挖掘机(ID:wAIsjwj)


前文传送门:

数据城堡参赛代码实战篇(一)---手把手教你使用pandas

数据城堡参赛代码实战篇(二)---使用pandas进行数据去重


关注Python爱好者社区,回复"数据代码",即可获得本文数据代码。


每天12点是小编最激动的时候,因为自己写的帖子又可以与大家见面啦,昨天把帖子传到某个大神组织的数据挖掘交流群时,某挖掘机朋友问了小编一个深刻的问题,题目看似很简单,但是以小编大脑里的知识系统来说,根本没有思路。此时,各路大神纷纷支招,问题顺利解决,小编也算涨了涨见识!所以小编今天想暂停一期数据城堡的代码实战,来带大家一探昨晚的究竟!

1 问题1

问题首先是这样的:



大神开始支招:



纳尼!字符串可以通过sum()进行拼接,简直颠覆了我的三观,吓得小编赶紧写代码一试:

df =pd.DataFrame([(0,'abc'),(0,'bcd'),(1,'efg')],columns=['id','str']) print (df.groupby(['id'])['str'].sum())

输出结果如下:

id 0    abcbcd 1       efg


居然真的可以,小编的知识真是太狭隘了,给好好上了一课,惭愧惭愧!

2 问题2

问题又来了,这次是这样的:



这时小编开始瞎搞,把后面的sum() 替换为join(' '),报错了!大神又开始支招了:



小编又亲自尝试了一番,代码如下:

df['str']=df['str'].apply(lambda x:' '+x) df1=df.groupby('id').sum() df1['str']=df1['str'].apply(lambda x:x[1:]) print (df1)

输出结果如下:

str id         0   abc bcd 1       efg

小编对这段代码的理解是这样的:第一行,我们首先对str列中的每一个值,通过一个匿名函数lambda进行处理,在每一个值前面加一个空格;随后我们根据id值进行分组并通过sum()运算进行连接,同时赋值给一个新的DataFrame;最后我们再通过一个匿名函数去掉开头的一个空格即可。


此时,另一位大神又来支招啦,使得我们的代码更加简洁:



代码实现是这样的:

df2=df.groupby(['id']).apply(lambda x:' '.join(x['str'])) print (df2)

输出如下:

id 0     abc  bcd 1          efg

仅仅用了一行,就实现了上面三行的功能,小编带你一同分析一下这句代码。首先仍然是根据id进行分组,我们来看一下分组之后的数据类型:

print (type(df.groupby(['id'])))

输出如下:

<class 'pandas.core.groupby.DataFrameGroupBy'>

可以看到,输出是一个DataFrameGroupBy对象,我们要怎么对这个对象进行预览呢?我们首先尝试如下代码:

for group in group_df: print (type(group)) print (group)

我们来看看输出:

<class 'tuple'> (0,    id   str 0   0   abc 1   0   bcd) <class 'tuple'> (1,    id   str 2   1   efg)

天呐,我们得到是一个个元组,这也太不好看了。其实,真正的预览方式应该是这样的:

for id, group in group_df:    print(type(group))    print(id)    print(group)

输出结果如下:

<class 'pandas.core.frame.DataFrame'> 0   id   str 0   0   abc 1   0   bcd <class 'pandas.core.frame.DataFrame'> 1   id   str 2   1   efg

这样就清晰很多了嘛,我们得到了每一个group都是DataFrame对象。


为什么会这样呢,这是因为前文所提到的DataFrameGroupBy对象是一个二元元组,由分组名(此处即id值)和数据块组成,因此在迭代的时候我们要指定两个参数,分别获取分组名和数据块,从而顺利完成遍历。


我们再来回顾一下上面的代码:

df2=df.groupby(['id']).apply(lambda x:' '.join(x['str']))

分组之后为什么直接作用于一个lambda函数上就能得到我们想要的效果呢,这是因为代码中的x是每一组的数据块,而不是一个二元元组,这是最关键的!然后我们对每一组的数据块通过一个空格进行连接即可,这里值得提醒大家的是当我们通过列名获得DataFrame中一列时,返回的是一个Series对象,它可直接使用join方法进行连接。

print (type(df['str'])) <class 'pandas.core.series.Series'>

3 总结


本篇,小编带你回顾了一下昨天发生在群里的一些小故事,并详细带大家分析了遇到的问题,希望大家有所收获!在此,特别感谢问题的提问者以及回答者(排名不分先后)@Winfield @self @穆文


小编也是一枚数据挖掘领域的小菜鸟,遇到问题不会是正常的,但是最主要的是一种虚心学习的态度,希望大家能与小编一起共同成长和进步!


关注Python爱好者社区,回复"数据代码",即可获得本文数据代码。

Python爱好者社区历史文章大合集

Python爱好者社区历史文章列表(每周append更新一次)

福利:文末扫码立刻关注公众号,“Python爱好者社区”,开始学习Python课程:

关注后在公众号内回复“课程”即可获取:

小编的Python入门视频课程!!!

崔老师爬虫实战案例免费学习视频。

丘老师数据科学入门指导免费学习视频。

陈老师数据分析报告制作免费学习视频。

玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。

丘老师Python网络爬虫实战免费学习视频。


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存