python字典求平均值_【数据科学系统学习】Python # 数据分析基本操作[四] 数据规整化和数据聚合与分组运算...

本篇内容为整理《利用Python进行数据分析》,博主使用代码为 Python3,部分内容和书本有出入。

在前几篇中我们介绍了 NumPy、pandas、matplotlib 三个库的基本操作,本篇介绍对数据的一些操作。

数据规整化:清理、转换、合并、重塑

数据聚合与分组运算

数据规整化:清理、转换、合并、重塑

合并数据集

pandas.merge:可根据一个或多个键将不同DataFrame中的行链接起来。

pandas.concat:可沿着一条轴将多个对象堆叠到一起。

combine_first:可将重复数据编接在一起,用一个对象中的值填充另一个对象中的缺失值。

数据库风格的 DataFrame 合并

数据集的合并或连接运算:通过一个或多个键将行链接起来。

bVbfdhY?w=1730&h=1312

多对一的合并:

bVbfdhZ?w=714&h=624

若没有指定用哪个列进行连接,merge会将重叠列名当做键,指定如下:

bVbfdh0?w=874&h=620

若两个对象的列名不同,可分别进行指定:

bVbfdh3?w=1508&h=924

默认情况下,merge做inner连接,结果中的键是交集。外连接求取的是键的并集:

bVbfdh5?w=890&h=740

多对多的合并操作:

bVbfdh8?w=1142&h=1292

连接方式只影响出现在结果中的键。

根据多个键进行合并,传入一个由列名组成的列表:

bVbfdh9?w=1368&h=944

在进行列-列连接时,DataFrame对象中的索引会被丢弃。

suffixes选项:指定附加到左右两个DataFrame对象的重叠列名上的字符串。

bVbfdia?w=1544&h=1230

索引上的合并

当DataFrame中的连接键位于其索引中时,传入left_index=True、 right_index=True,以说明索引应该被用作连接键:

bVbfdi0?w=1614&h=1222

bVbfdi8?w=1458&h=560

对于层次化索引的数据:

bVbfdju?w=1902&h=1308

必须以列表的形式指明用作合并键的列(注意对重复索引值的处理):

bVbfdjv?w=1634&h=558

使用合并双方的索引:

bVbfdjw?w=1742&h=572

DataFrame的 join 实例方法:

bVbfdjx?w=1060&h=546

bVbfdjB?w=892&h=900

更方便的实现按索引合并,不管有没有重叠的列。在连接键上作左连接。

支持参数DataFrame的索引跟调用者DataFrame的某个列之间的连接:

bVbfdjD?w=918&h=618

bVbfdjG?w=856&h=952

对于简单的索引合并,可以向join传入一组DataFrame(concat 函数也是这个功能):

bVbfdjH?w=1908&h=1068

轴向连接

数据合并运算:

连接(concatenation)

绑定(binding)

堆叠(stacking)

NumPy有一个用于合并原始NumPy数组的concatenation函数:

bVbfdj6?w=1268&h=632

pandas的concat函数:

bVbfdkh?w=1206&h=780

默认情况下,concat在 axis=0 上工作,产生一个新Series。传入 axis=1,产生一个DataFrame:

bVbfdkv?w=926&h=678

这种情况下,另外一条轴上没有重叠,传入 join = 'inner' 得到它们的交集:

bVbfdkw?w=1208&h=358

使用 key 参数,在连接轴上创建一个层次化索引:

bVbfdkx?w=1572&h=966

沿着 axis=1 对Series进行合并,keys 就会成为DataFrame的列头:

bVbfdky?w=1558&h=476

对DataFrame对象也是如此:

bVbfdkG?w=1656&h=772

传入一个字典,则字典的键会被当做keys选项的值:

bVbfdkI?w=1294&h=472

用于管理层次化索引创建方式的参数:

bVbfdkK?w=1566&h=532

跟当前分析工作无关的DataFrame行索引:

bVbfdkL?w=1662&h=976

传入 ignore_index = True:

bVbfdkM?w=1230&h=1120

合并重叠数据

关于有索引全部或部分重叠的两个数据集。

NumPy的where函数,用于表达一种矢量化的if-else:

bVbfdpY?w=1460&h=1266

bVbfdqf?w=1160&h=210

Series的combine_first方法,实现与上面一样的功能,并会进行数据对齐:

bVbfdqq?w=910&h=442

对于DataFrame 一样:

bVbfdqs?w=1262&h=874

bVbfdqt?w=948&h=1020

可以看作用参数对象中的数据为调用者对象的缺失数据“打补丁”。

重塑和轴向旋转

用于重新排列表格型数据的基础运算:重塑(reshape)或轴向旋转(pivot)。

重塑层次化索引

stark:将数据的列“旋转”为行

unstark:将数据的行“旋转”为列

bVbfdqE?w=1782&h=598

用stack方法将行转为列,得到一个Series:

bVbfdqF?w=880&h=596

对层次化索引的Series,可以用unstack将其重新排为一个DataFrame:

bVbfdqG?w=766&h=414

默认情况下,unstack操作最内层。

传入分层级别的编号或名称可对其他级别进行unstack操作:

bVbfdqH?w=942&h=974

如果不是所有的级别值都能在各分组找到的话,unstack操作可能会引入缺失数据:

bVbfdqJ?w=1336&h=618

stack默认会滤除缺失数据,因此该运算是可逆的:

bVbfdqK?w=1072&h=1074

对DataFrame进行unstack操作时,作为旋转轴的级别将会成为结果中的最低级别:

bVbfdqL?w=1682&h=826

bVbfdAV?w=1418&h=1242

将“长格式”旋转为“宽格式”

时间序列数据通常以 “长格式(long)”或“堆叠格式(stacked)”存储在数据库和 CSV 中。

bVbfdAY?w=882&h=600

转成DataFrame,用 pivot 方法:

bVbfdAZ?w=1416&h=202

bVbfdA0?w=718&h=624

得到的DataFrame带有层次化的列:

bVbfdBw?w=1250&h=982

假设有两个需要参与重塑的数据列:

bVbfdBB?w=1352&h=722

pivot其实只是一个快捷方式:用set_index创建层次化索引,再用unstack重塑。

bVbfdBC?w=1638&h=590

以上是数据的重排,下面是过滤、清理及其他转换工作。

数据转换

移除重复数据

DataFrame中出现的重复行:

bVbfdBG?w=1464&h=798

DataFrame的duplicated方法返回一个布尔型Series,表示各行是否是重复行,drop_duplicates方法返回一个移除了重复行的DataFrame:

bVbfdBH?w=910&h=954

指定部分列进行重复项判断,如只希望根据k1列过滤重复项:

bVbfdBI?w=1008&h=462

duplicated和drop_duplicates默认保留重复数值里第一次出现的组合,传入keep = last则保留最后一个:

bVbfdBJ?w=1358&h=986

利用函数或映射进行数据转换

根据数组、Series或DataFrame列中的值来实现转换。

bVbfdBU?w=1712&h=982

编写一个肉类到动物的映射:

bVbfdBW?w=1030&h=412

Series的map方法:可以接受一个函数或含有映射关系的字典型对象,用于修改对象的数据子集。

bVbfdBY?w=1704&h=902

也可以传入一个能够完成全部这些工作的函数:

bVbfdBZ?w=1478&h=566

替换值

replace方法 :替换

利用fillna方法填充缺失数据可以看作替换的一种特殊情况。

替换一个值和一次性替换多个值:

bVbfdB5?w=1402&h=1306

对不同的值进行不同的替换:

bVbfdCb?w=1214&h=446

传入的参数也可以是字典:

bVbfdCc?w=1144&h=434

重命名轴索引

轴标签有一个map方法:

bVbfdCg?w=1598&h=374

对函数或映射进行转换,从而得到一个新对象。

将其值赋给index,就可以对DataFrame进行就地修改了:

bVbfdCr?w=1156&h=496

要创建数据集的转换版,而不是修改原始数据,用rename:

bVbfdCs?w=1328&h=428

rename结合字典型对象可以实现对部分轴标签的更新:

bVbfdCt?w=1164&h=484

rename实现了复制DataFrame并对其索引和列标签进行赋值,就地修改某个数据集,传入inplace=True:

bVbfdCu?w=1490&h=470

离散化和面元划分

为了便于分析,连续数据常常被离散化或拆分为“面元(bin)”。

用pandas的cut函数:

bVbfdCz?w=2296&h=566

pandas返回的是一个特殊的Categorical对象,它含有一个表示不同分类名称的数组和一个为年龄数据进行标号的属性:

bVbfdCA?w=1512&h=444

哪边是闭端可以通过right=False进行修改:

bVbfdCB?w=2270&h=308

设置自己的面元名称:

bVbfdCC?w=2262&h=334

将labels选项设置为一个列表或数组即可。

如果向cut传入的是面元的数量而不是确切的面元边界,则它会根据数据的最小值和最大值计算等长面元:

bVbfdCE?w=2288&h=464

将一些均匀分布的数据分成了四组。

qcut函数:根据样本分位数对数据进行面元划分。

由于qcut使用的是样本分位数,可以得到大小基本相等的面元(而 cut 根据数据的分布情况,可能无法使各个面元中含有相同数量的数据点)。

bVbfdCF?w=2318&h=512

bVbfdCH?w=910&h=374

设置自定义的分位数:

bVbfdCI?w=2260&h=320

在聚合和分组运算时会再次用到cut 和 qcut 这两个离散化函数。

检测和过滤异常值

判断是否存在异常值(outlier ):

bVbfdCJ?w=1318&h=938

找出某列中绝对值大小超过 3 的值:

bVbfdCK?w=814&h=414

选出全部含有“超过 3 或 -3 的值”的行:

bVbfdCL?w=1124&h=936

将值限制在区间 -3 到 3 以内:

bVbfdCM?w=1246&h=814

np.sign这个ufunc返回的是一个由 1 和 -1 组成的数组,表示原始值的符号。

排列和随机采样

numpy.random.permutation函数:对Series和DataFrame的列排列。

bVbfdCS?w=1318&h=310

Permutation(5):需要排列的轴的长度。

然后就可以在基于ix的索引操作或take函数中使用该数组了:

bVbfdCW?w=1030&h=1074

选取随机子集(非替换):

bVbfdC1?w=1348&h=422

用替换的方式产生样本:

bVbfdC2?w=1446&h=678

计算指标/哑变量

将分类变量(Categorical)转换为“哑变量矩阵(dummy matrix)”或“指标矩阵(indicator matrix)”。

bVbfdC6?w=1466&h=1324

给DataFrame的列加上一个前缀,以便能够跟其他数据进行合并:

bVbfdC9?w=1546&h=852

用get_dummies的prefix参数。

DataFrame中的某行同属于多个分类的情况,举个例子:

bVbfdDr?w=2290&h=1302

要为每个genre添加指标变量就需要做一些数据规整操作,构建多成员指标变量:

bVbfdDv?w=1976&h=1316

对于很大的数据,这种方式会变得非常慢,需要编写一个能够利用DataFrame内部机制的更低级的函数:

bVbfdDI?w=1786&h=1242

用get_dummies和cut之类的离散化函数。

字符串操作

字符串对象方法

Python 字符串对象的内置方法:

bVbfdDT?w=1244&h=852

find找不到返回 -1,index找不到引发一个异常

bVbfdD0?w=1904&h=962

传入空字符串常常用于删除模式:

bVbfdD2?w=1040&h=544

正则表达式(regex)

提供了一种灵活的在文本中搜索或匹配字符串模式的方式。python 内置的re模块负责对字符串应用正则表达式。

re模块的函数分为三个大类:模式匹配、替换、拆分。

bVbfdD8?w=1312&h=656

描述一个或多个空白符的regex是 \s+。

调用re.split('\s+', text)时,正则表达式会先被编译,然后再在text上调用其split方法。

可以用re.compile自己编译一个regex,以得到一个可重用的regex对象,如上所示。如果打算对许多字符串应用同一条正则表达式,强烈建议通过这种方法,可以节省大量的 CPU 时间。

得到匹配regex的所有模式:

bVbfdEa?w=912&h=162

findall:返回字符串中所有的匹配项。

search:只返回第一个匹配项。

match:只匹配字符串的首部。

bVbfdEu?w=2282&h=1166

sub方法:将匹配到的模式替换为指定字符串,并返回所得到的新字符串。

bVbfdEy?w=1154&h=316

不仅想找出电子邮件地址,还想将各个地址分为 3 个部分,只需将待分段的模式的各部分用圆括号包起来:

bVbfdEA?w=1560&h=372

通过groups方法返回一个由模式各段组成的元组。

对于带有分组功能的模式,findall会返回一个元组列表:

bVbfdEC?w=922&h=296

sub还能通过诸如\1, \2之类的特殊符号访问各匹配项中的分组:

bVbfdED?w=1640&h=330

为各个匹配分组加上一个名称,由这种正则表达式所产生的匹配对象可以得到一个简单易用的带有分组名称的字典:

bVbfdEF?w=1652&h=558

pandas 中矢量化的字符串函数

通过data.map,所有字符串和正则表达式方法都能被应用于各个值,但如存在NA就会报错,为了解决这个问题,Series有一些能够跳过NA值的字符串操作方法,通过Series的str属性即可访问这些方法:

bVbfdEO?w=1768&h=1170

也可以用正则表达式:

bVbfdEQ?w=1342&h=520

实现矢量化的元素获取操作,对str.get/str属性上使用索引:

bVbfdER?w=1544&h=1100

对字符串进行子串截取:

bVbfdEX?w=646&h=340

数据聚合与分组运算

对数据集进行分组并对各组应用一个函数。

在将数据集准备好之后,通常的任务就是计算分组统计或生成透视表。pandas提供了一个灵活高效的gruopby功能,对数据集进行切片、切块、摘要等操作。

用 python 和pandas强大的表达能力可以执行复杂的多的分组运算:利用任何可以接受pandas对象或NumPy数组的函数。

GroupBy技术

分组运算:split(拆分)--apply(应用)--combine(合并)。

分组键的形式:

列表或数组,其长度与待分组的轴一样。

表示DataFrame某个列名的值。

字典或Series,给出待分组轴上的值与分组名之间的对应关系。

函数,用于处理轴索引或索引中的各个标签。

bVbfdFc?w=1556&h=942

访问data1,并根据key1调用groupby。

变量grouped是一个GroupBy对象,它实际上还没有进行任何计算,只是含有一些有关分组键df['key1']的中间数据。

例如,调用GroupBy的mean方法来计算分组平均值:

bVbfdFe?w=1636&h=732

Series根据分组键进行了聚合,产生了一个新的Series,其索引为key1列中的唯一值。

通过两个键对数据进行了分组后,得到的Series具有一个层次化索引:

bVbfdFk?w=758&h=416

分组键可以是任何长度适当的数组:

bVbfdFl?w=1746&h=492

将列名用作分组键:

bVbfdFm?w=1052&h=960

GroupBy的size方法返回一个含有分组大小的Series:

bVbfdFo?w=784&h=372

对分组进行迭代

GroupBy对象支持迭代,可以产生一组二元元组(由分组名和数据块组成)。

bVbfdFx?w=1444&h=1328

对于多重键,元组的第一个元素将会是由键值组成的元组。

对数据片段进行操作,如将这些数据片段做成一个字典:

bVbfdFO?w=1208&h=426

groupby默认在axis=0上进行分组,通过设置可以在其它任何轴上进行分组,如可以根据dtype对列进行分组:

bVbfdFT?w=1338&h=1054

选取一个或一组列

对于由DataFrame产生的GroupBy对象,用一个或一组(单个字符串或字符串数组)列名对其进行索引,就能实现选取部分列进行聚合的目的:

bVbfdFU?w=1660&h=432

例如,对部分列进行聚合:计算data2列的平均值并以DataFrame形式得到结果:

bVbfdFV?w=1326&h=560

返回一个已分组的DataFrame(传入的是列表或数组)或Series(传入的是标量形式的单个列名):

bVbfdFY?w=1670&h=598

通过字典或 Series 进行分组

除数组以外,分组信息还可以其他形式存在

bVbfdF3?w=1916&h=854

根据分组计算列的sum:

bVbfdF4?w=1350&h=728

将mapping这个字典传给groupby即可。

用Series作为分组键:

bVbfdF9?w=1176&h=1012

这里Series可以被看做一个固定大小的映射。pandas会检查Series以确保其索引根分组轴是对齐的。

通过函数进行分组

任何被当做分组键的函数都会在各个索引值上被调用一次,其返回值就会被用作分组名称。

bVbfdGc?w=1300&h=408

将函数根数组、列表、字典、Series混合使用(任何东西最终都会被转换为数组):

bVbfdGj?w=1320&h=574

Key_list和人名对应,再在相同长度的对应一列里选min的值。

根据索引级别分组

层次化索引数据集通过level关键字传入级别编号或名称:

bVbfdGo?w=1824&h=1218

数据聚合

可以使用经过优化的GroupBy的方法,还可以使用自己发明的聚合运算,还可以调用分组对象上已经定义好的任何方法,如 quantile可以计算Series或DataFrame列的样本分位数:

bVbfdHg?w=1066&h=874

GroupBy会高效地对Series进行切片,然后对各片调用piece.quantile(0.9),最后将这些结果组装成最终结果。

使用自己的聚合函数,传入aggregate或agg方法即可:

bVbfdHi?w=1094&h=544

有些方法如describe也可以用,但严格来讲它们并非聚合运算。

bVbfdHk?w=2308&h=504

自定义聚合函数比表中的经过优化的函数慢得多,这是因为在构造中间分组数据块时存在非常大的开销(函数调用、数据重排等)。

面向列的多函数应用

根据 'smoker' 和 'size' 对 tips 进行分组:

bVbfdHn?w=1278&h=822

传入一组函数或函数名,得到的DataFrame的列就会以相应的函数命名:

bVbfdHo?w=1324&h=984

传入一个由(name, function )元组组成的列表,各元组的第一个元素会被用作DataFrame的列名:

bVbfdHp?w=1560&h=1004

对于DataFrame,定义一组应用于全部列的函数,或不同的列应用不同的函数。

bVbfdHq?w=1542&h=1136

结果的DataFrame拥有层次化的列。相当于分别对列['tip_pct']和列['total_bill']进行聚合,然后用concat将结果组装到一起(列名用作 keys 参数)。

传入带有自定义名称的元组列表:

bVbfdHr?w=1588&h=1106

对不同的列应用不同的函数:向agg传入一个从列名映射到函数的字典

bVbfdHs?w=1336&h=990

只有将多个函数应用到至少一列时,DataFrame才会拥有层次化的列:

bVbfdHt?w=1556&h=1104

以“无索引”的形式返回聚合数据

向groupby传入as_index=False,禁用功能由唯一的分组键组成索引:

bVbfdHu?w=1498&h=906

bVbfdHv?w=1140&h=978

分组级运算和转换

聚合只是分组运算的其中一种,它接受能够将一维数据简化为标量值的函数。

接下来介绍 transform 和 apply 方法,执行更多其他的分组运算。

为一个DataFrame添加一个用于存放各索引分组平均值的列:先聚合再合并。

bVbfdHx?w=1022&h=552

bVbfdHy?w=1500&h=986

下面在GroupBy上使用transform方法:

bVbfdHz?w=1358&h=1010

bVbfdHA?w=1286&h=540

transform会将一个函数应用到各个分组,然后将结果放置到适当的位置上。

从各组中减去平均值:先创建一个距平化函数(demeaning function),然后将其传给transform。

bVbfdHB?w=1322&h=744

检查demeaned现在的分组平均值是否为 0:

bVbfdHC?w=1524&h=316

跟aggregate一样,transform也是一个有着严格条件的特殊函数,传入的函数只能产生两种结果,一个可以广播的标量值(如 np.mean) 或一个相同大小的结果数组。

apply:一般性的“拆分-应用-合并”

最一般化的GroupBy方法是apply:apply会将待处理的对象拆分成多个片段,然后对各片段调用传入的函数,最后尝试将各片段组合到一起。

根据分组选出最高的 5 个tip_pct值:编写一个函数,在指定列找出最大值,然后把这个值所在的行选取出来。

bVbfdHD?w=1406&h=754

对smoker分组并用该分组函数调用apply,得到:

bVbfdHE?w=1344&h=922

top函数在DataFrame的各个片段上调用,然后结果由pandas.concat组装到一起,并以分组名称进行了标记。

最后结果就有了一个层次化索引,其内层索引值来自原DataFrame。

如果传给apply的函数能够接受其他参数或关键字,可以将这些内容放在函数名后面一并传入:

bVbfdHF?w=1772&h=816

在GroupBy对象上调用describe:

bVbfdHG?w=1598&h=1300

在GroupBy中,当调用如describe之类的方法时,实际上只是应用了下面两条代码的快捷方式:

bVbfdHH?w=1330&h=1096

除这些基本用法之外,能否充分发挥apply的威力很大程度上取决于你的创造力,传入的哪个函数能做什么全由你说了算,它只需返回一个pandas 对象或标量值即可。

禁止分组键

分组键会跟原始对象的索引共同构成结果对象中的层次化索引,将group_keys=False传入groupby即可禁止该效果:

bVbfdHK?w=1362&h=936

bVbfdHL?w=1414&h=872

分位数和桶分析

pandas有一些能根据指定面元或样本分位数将数据拆分成多块的工具(cut 和 qcut),将这些函数跟groupby结合起来,就能非常轻松地实现对数据集的桶或分位数分析了。

桶:bucket

分位数:quantile

“长度相等的桶”指的是“区间大小相等”,“大小相等的桶”指的是“数据点数量相等”。

利用cut将其装入长度相等的桶中:

bVbfdHM?w=2314&h=822

由cut返回的Factor对象可直接用于groupby,可以对data2做一些统计计算:

bVbfdHO?w=1648&h=1012

要根据样本分位数得到大小相等的桶,使用qcut:

bVbfdHQ?w=1732&h=1042

传入labels=False,即可只获取分位数的编号。否则那段还是区间而不是编号:

bVbfdHS?w=1448&h=1052

示例:用特定于分组的值填充缺失值

对于缺失数据的清理工作,有时用dropna将其滤除,有时则希望用一个固定值或由数据集本身所衍生出来的值去填充NA值,用fillna这个工具。

如用平均值去填充NA值:

bVbfdHT?w=1048&h=924

对不同的分组填充不同的值:将数据分组,并使用apply和一个能够对各数据块调用fillna的函数即可。

bVbfdHU?w=2288&h=1118

用这个分组平均值去填充NA值:

bVbfdHV?w=1262&h=568

也可以在代码中预定义各组的填充值,由于分组具有一个name 属性:

bVbfdHW?w=1442&h=692

bVbfdHX?w=2258&h=926

示例:随机采样和排列

从一个大数据集中随机抽取样本以进行蒙特卡罗模拟(Monte Carlo simulation)或其他分析工作。抽取的方式很多,其中的一些效率会比其他的高很多

一个办法是:选取np.random.permutation(N)的前K个元素,其中N为完整数据的大小,K为期望的样本大小。

构造一副扑克牌:

bVbfdHY?w=1564&h=1160

从整副牌中抽出 5 张:

bVbfdHZ?w=1570&h=540

从每种花色中随机抽取两张牌,由于花色是牌名的最后一个字符,可以据此进行分组,并使用apply:

bVbfdH0?w=1414&h=562

另一种方法:

bVbfdH1?w=1552&h=522

示例:分组加权平均数和相关系数

例如对这个数据集利用category计算分组加权平均数:

bVbfdH2?w=1752&h=1266

来自 Yahoo! Finance 的数据集:

bVbfdH3?w=888&h=650

计算一个由日收益率(通过百分数变化计算)与 SPX 之间的年度相关系数组成的DataFrame:

bVbfdH4?w=1820&h=990

计算列于列之间的相关系数:(苹果和微软的年度相关系数)

bVbfdH5?w=1424&h=836

示例:面向分组的线性回归

还是上个例子,定义下面这个regress函数(利用 statsmodels 库)对各数据块执行普通最小二乘法回归(Ordinary Least Squares, OLS)。

按年计算 AAPL 对 SPX 收益率的线性回归:

bVbfdH6?w=1334&h=1244

透视表和交叉表

透视表(pivot table)

是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上的分组键将数据分配到各个矩形区域中。

在小费数据集中,根据day和smoker计算分组平均数(pivot_table 的默认聚合类型):

bVbfdH8?w=1260&h=808

只想聚合tip_pct和size,并根据day进行分组:

bVbfdH9?w=1646&h=790

传入margins=True添加分项小计,将会添加标签为All的行和列,其值对应于单个等级中所有数据的分组统计。

bVbfdIa?w=1580&h=830

这里All值为平均数。

要使用其他的聚合函数,将其传给aggfunc即可。例如使用count或len得到有关分组大小的交叉表:

bVbfdIb?w=1770&h=682

存在NA值,就设置一个fill_value:

bVbfdIc?w=1684&h=1116

交叉表(crosstab)

是一种用于计算分组频率的特殊透视表。

bVbfdId?w=1326&h=1288

用pandas.crosstab函数(pivot_table 也能实现该功能:根据 Nationality 和 Handedness 对这段数据进行汇总):

bVbfdIe?w=1642&h=484

crosstab的前两个参数可以是数组、Series、数组列表:

bVbfdIf?w=1696&h=758

示例:2012联邦选举委员会数据库

加载数据

bVbfdIg?w=2008&h=1330

抽取有关赞助人和赞助模式的统计信息。

通过unique,可以获取全部的候选人名单:

bVbfdIh?w=1850&h=1186

利用字典说明党派关系:

bVbfdIi?w=1524&h=628

通过这个映射以及 Series对象的map方法,可以根据候选人姓名得到一组党派信息:

bVbfdIj?w=1680&h=1098

注意,该数据集既包括赞助也包括退款(负的出资额),为了简化分析过程,限定该数据集只能有正的出资额:

bVbfdIk?w=1262&h=372

由于 Barack Obama 和 Mitt Romney 是最主要的两名候选人,专门准备了一个子集,只包含针对他们两人的竞选活动的赞助信息:

bVbfdIl?w=1718&h=110

根据职业和雇主统计赞助信息

首先,根据职业计算出资总额:

bVbfdIm?w=1380&h=606

这里只列出了前10个,注意到 许多职业都涉及相同的基本工作类型或同一样东西有多种变体,清理一些这样的数据:将一个职业信息映射到另一个。

bVbfdIn?w=2318&h=1306

对雇主信息也进行了同样的处理。

这里利用了dict.get,它允许没有映射关系的职业也能“通过”。

现在,可以通过pivot_table根据党派和职业对数据进行聚合,然后过滤掉总出资额不足 200 万美元对数据:

bVbfdIo?w=1764&h=1240

做成柱状图:

bVbfdIp?w=1564&h=1048

对 Obama 和 Romney 总出资额最高的职业和企业:先对候选人进行分组,然后求取最大值:

bVbfdIq?w=1778&h=1044

bVbfdIr?w=1836&h=1080

对出资额分组

利用cut函数根据出资额的大小将数据离散化到多个面元中:

bVbfdIs?w=1622&h=1296

bVbfdIt?w=1986&h=974

根据候选人姓名以及面元标签对数据进行分组:

bVbfdIu?w=1366&h=850

对出资额求和并在面元内规格化,以便图形化显示两位候选人各种赞助额度的比例:

bVbfdIv?w=1574&h=848

bVbfdIw?w=1564&h=856

bVbfdIx?w=1564&h=790

根据州统计赞助信息

首先,根据候选人和州对数据进行聚合:

bVbfdIz?w=1662&h=1046

对各行除以总赞助额,就得到各候选人在各州的总赞助额比例:

bVbfcW3?w=1278&h=956

bVbfcW3?w=1278&h=956

不足之处,欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据离散是将连续型数据划分为有限数量的离散区间的过程。在Python中,可以使用以下方法进行数据离散: 1. 使用cut函数:cut函数是pandas库中的一个函数,可以将数据分段为离散的区间。它可以根据指定的分段数目或者自定义的分段边界对数据进行离散。下面是一个示例代码: ```python import pandas as pd # 创建一个示例数据集 data = pd.DataFrame({'score': [80, 90, 85, 70, 60, 50, 75]}) # 使用cut函数进行离散,默认分为4个区间 data['score_category'] = pd.cut(data['score'], 4) # 打印结果 print(data) ``` 运行以上代码会将得分分成4个离散的区间,并添加一个新的列'score_category',表示每个数据所属的区间。 2. 使用qcut函数:qcut函数也是pandas库中的一个函数,可以根据数据的分位数进行离散。它可以根据指定的分段数目或者自定义的分位数对数据进行离散。下面是一个示例代码: ```python import pandas as pd # 创建一个示例数据集 data = pd.DataFrame({'score': [80, 90, 85, 70, 60, 50, 75]}) # 使用qcut函数进行离散,默认分为4个区间 data['score_category'] = pd.qcut(data['score'], 4) # 打印结果 print(data) ``` 运行以上代码会将得分分成4个离散的区间,并添加一个新的列'score_category',表示每个数据所属的区间。 这些方法可以根据具体的需选择使用,根据数据的特点和分布情况来确定合适的离散方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值