Python, Pandas,跨行求不同类别的百分比

《求更好解决办法》

1. 问题描述

1.1 相关材料

CSV文档:

  每一行包含一个候选人,和他参选选区的相关信息,详情如下:

              "election_year": 选举年份。可能的取值为 “2011” 和 "2015年" ;

                "cacode" :    选区编号。2011年和2015年的 “选区编号”,可能不一致,例如,A11选区在2011年出现,但在2015年则没有该选区;

                “camp”:        阵营。每个候选人可能来自三个不同的阵营(泛,建,其它);

                "is_elected":    是否当选。Y: 当选,N: 落选;

                "candidate_num":    候选人编号;

                “vote”:    所得票数。

图1. 2011年,选区A01-A04
图2. 2015年,选区A01-A04

1.2 要解决的问题

对每一年(2011,2015)每个选区(例. A01, B03)中的所有参选人,基于每位参选人的阵营(“camp”),和每个阵营(“camp”)所得票数(vote)。

计算出,某年,某个选区中,不同阵营(“camp”)的得票率。

如 “图3. 期待结果” 所示:希望得到一个CSV 文档,里面的新增的列名和含义为:

                “winnerCamp”: 当选者("is_elected=Y") 所属的阵营(“camp”)

                "fanTotal":    该选区,在该选举年份(2011,或2015),阵营("camp")为“泛” 的所有候选人,所得票数总和

                “jianTotal":    该选区,在该选举年份(2011,或2015),阵营("camp")为“建” 的所有候选人,所得票数总和

                “otherTotal":    该选区,在该选举年份(2011,或2015),阵营("camp")为“其它” 的所有候选人,所得票数总和           

                "fanPercent"/ "jianPercent"/ "otherPercent":    该选区,在该选举年份(2011,或2015),三个阵营("camp"): "泛"/ “建”/ “其它” ,各自所得票数的百分比

图3. 期待结果


1.3 难点总结

1.3.1 如 “图4. 自动当选,没有票数”  所示,如果候选人的编(“candidate_num”)是 “noCompetitor” ,则不需要计算,该选区,在该选举年份中,各个阵营("camp")所得票数的百分比。

图4. 自动当选,没有票数

1.3.2 选举年份2011 和 2015 包含的选区可能不完全相同。 即,选区A09在2011年出现,但可能在2015年没有该选区。

2. 现有解决思路

Step 1.  对 CSV 表格中列 “cacode” 和 列 "election_year" 按照 A-Z 升序排列,确保某年,某个选区的所有候选人,依次排列在一起, 而不是散落到CSV文档的不同位置。效果如图1,图2;

Step 2. 用Pandas 读入CSV文档

图5. 读入排序后的CSV文档

Step 3. 定义一个方法,

def groubCacodeByYear(startRow, dataPure):

Step 3.1 该方法的输入和输出为

          输入参数:"startRow", 数据类型为: int ,用来定位,“dataPure” 中的DataFrame(即,CSV文档中的行)

          输入参数:“dataPure”,数据类型为:DataFrame,稍后会用被遍历

          输出参数:“groupLength”, 数据类型为:int, 用于刷新遍历DataFrame的下标

return groupLength

Step 3.2 该方法的实现细节:

根据输入参数“startRow”,通过Pandas.DataFrame.iloc[]方法,得到下标等于“startRow”的DataFrame(行)。从而,得到该DataFrame(行)中,列名“election_year” 和列名“cacode”的值。

如下“ 图6. DataFrame.iloc[ ] “  所示: 得到给定下标的DataFrame(行),列名为 “election_year”和“cacode”的值。

图6. DataFrame.iloc[ ]

Step 3.3 得到所有行,这些行有着相同的列(“election_year” 和 “cocode”的)值,分别为 “yearInit” 和 "cacodeInit"。

即,取得读入的DataFrame: dataPure中,所有相同的选举年份,和选区编号的行。接着,计算所得到DataFrame的行数,并赋值给 输出参数:groupLength,如图7

图7. 取得某年,某选区的所有参选人所在的行

Step 3.4 在某年,某个选区所有候选人组成的, 变量名为“candidates” 的DataFrame中,取得

    “winnerCamp”:    当选者来自的阵营(camp)

    "isAutowin":        当选者的候选编号(canditate_num)

    "commonCacode":    所有候选人,共同的选区编号(cacode)

    "commonYear":        所有候选人,共同的选举年份(election_year)


图8. 取得某年,某选区,参选者的相关信息

Step 3.5  若变量“isAutowin”的值,不等于“noCompetitor”,则代表该年,该选区,有多于1位候选人,需要选民投票,可以计算各个阵营(camp)所得票数的百分比;

反之,若变量“isAutowin”的值,等于“noCompetitor”,则代表该年,该选区,只有一个人参与,不需要投票,不需要计算各个阵营的所得票数的百分比。

Step 3.5.1  变量“isAutowin”的值,不等于“noCompetitor”, 需计算各个阵营( camp )所得票数的百分比,代码如下:

if isAutowin != 'noCompetitor':

得到某年、某选区里,每个候选人所得票数。根据每个候选人,各自所属的阵营(camp)将该票数,追加到相应的数组里面,代码如图9:

图9. 取得某年,某选区,所有候选人的=所得票数,和各自所属阵营

计算某年,某选区,所有阵营(Camp)所得票数的百分比,代码如图10:

图10. 计算各个阵营所得票数的百分比

将上述计算求得的结果:

            "fanTotal":     某年,某选区,所有阵营(camp)为“泛” 的候选人,得票总和

          "jinaTotal":    某年,某选区,所有阵营(camp)为“建” 的候选人,得票总和

            "otherTotal":    某年,某选区,所有阵营(camp)为“其它” 的候选人,得票总和

  "fanPercent" / "jianPercent" / "otherPercent" : 某年,某选区,三大阵营的得票率

通过Pandas 创建DataFrame,并追加到指定路径的CSV文档中,如图11:

图11. 将计算结果追加到CSV文档

Step 3.5.2  变量“isAutowin”的值,等于“noCompetitor”, 该年,该选区,只有以为参选人:

    不需要计算各个阵营(camp)的得票率;

    但,需要将输出参数:“groupLength” 设为:1。即,某年,某选区,只有一位候选人

如图12:

图12: 某年,某选区,只有一位候选人,不需要计算各个阵营得票率

Step 3.6

        返回输出参数:“groupLength”(下一行要重复Step3.1 -Step 3.6)的DataFrame的下标

return groupLength

该方法的完整代码如下图13

图13: 完整的代码

Step 4.  遍历 Step2 中读入的DataFrame,并使用 Step 3定义的方法,如下图14:

当指针" i " 的数值,小于 Step2 中读入的DataFrame的行数时,会使用Step 3 中定义的方法,先判断该年,该选区,是否只有一人参选,

若是,则返回将“moveStep”赋值为1;

若否,则计算并保存某年、某个选区(cacode),不同阵营(Camp)的得票率,将“moveStep” 赋值为该区,这次选区的参选人数。

图14. 遍历要处理的CSV




最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容