未加星标

利用Python进行数据分析(十一)之数据规整化

字体大小 | |
[挖掘分析应用 所属分类 挖掘分析应用 | 发布者 店小二04 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏
数据规整化
重塑和轴向旋转

对表格型数据重新排列。

重塑层次化索引

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

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

data:
number one two three
state
Ohio 0 1 2
Colorado 3 4 5

data.stack()结果如下:为一个Series

state number
Ohio one 0 two 1 three 2
Colorado one 3 two 4 three 5

反过来就是用unstack()

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

长格式为全部列像关系型数据库(如mysql)存储,固定架构,后续增加数据或者删除,数据只会越来越长。但是缺点是数据操作不方便。因为都是一行做一个数据,看上去数据就特别多,但是如果将一个作为索引,就能减少一定量的数据级,但是数据量并没减少。

pivoted = ldata.pivot('date', 'item', 'value')
#用DataFrame的pivot的方法实现date作行索引,item做列,value为值。
#但是pivot只是一个快捷方式,并没有改变源数据的格式,所以如果需要改变源格式,需要结合上面重塑层次化索引来操作:
unstacked = ldata.set_index(['date','item']).unstack('item')
数据转换

前面提到的是对数据进行重排,另一类重要操作则是过滤、清理以及其他的

转换工作。

移除重复操作

DataFrame中出现了重复行时:

data:
k1 k2
o one 1
I one 1
2 one 2
3 two 3
4 two 3
5 two 4
6 two 4
# 返回每行是否为重复行(与之前的列比较,所以第一次出现时是false,第二次及之后就是true了)
data.duplicated() :
0 False
1 True
2 False
3 False
4 True
5 False
6 True
#返回移除了重复行的DataFrame(默认判断所有列)
data.drop_duplicates()
#返回移除了重复行的DataFrame(只判断某列)
data.drop_duplicates(['k1'])
#drop_duplicates默认保留的是第一次出现的组合,传入take_last=True则保留最后一个:
data.drop_duplicates(['k1','k2'],take_last=True)
利用函数或映射进行数据转换

假设一个data如下:

data:
food ounces
0 bacon 4.0
1 pulled pork 3.0
2 bacon 12.0
3 Pastrami 6.0
4 corned beef 7.5
S Bacon 8.0
6 pastrami 3.0
7 honey ham 5.0
8 nova lox 6.0

如果想添加一列表明该food来源的动物类型,需要先编写一个肉类到动物的映射:

meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}

如何增加上去,注意到有的肉类有大写,str.lower为一个函数,可以放在Series的map方法中,再把映射也可以放进来:

data['animal'] = data['food'].map(str.lower).map(meat_to_animal)

而使用lambda则更简洁:

data['animal'] = data['food'].map(lambda x:meat_to_animal[x..lower()])
替换值

之前处理缺失时,使用fillna方法填充可以看作是一种特殊情况,前面的map当然也可以用来替换,但是replace是一种更方便灵活的方法。

#把data的-999替换为缺失值
data.replace(-999,np.nan)
#一次替换多个值
data.replace([-999,-1000],np.nan)
#对多个不同值不同的替换,使用替换关系组成的列表即可
data.replace([-999,-1000],[np.nan,0])
#或者传入字典
data.replace({-999:np.nan,-1000:0})
重命名轴索引

对轴索引重新命名,也可以使用map来传入一个函数等操作

#如下 对index索引名字大写
data.index = data.index.map(str.upper)

如果想创建数据集的转换版而不是修改原始数据,则可以使用rename:

data.rename(index = str.title,columns =str.upper)
#index首字母大写,columns全部大写
#传入字典即可对部分轴标签替换'OHIO'替换为 'INDIANA','three'替换'peekaboo'
data.rename(index={'OHIO': 'INDIANA'},columns={'three': 'peekaboo'})

rename不是修改源数据,如果想直接修改,在rename内直接传入inplace=True即可。

离散化和面元划分

我的理解就是对一组数据划分到不同的组内:

假设有一组人员数据,而你希望将它们划分为不同的年龄组。

In [153]: ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]

接下来将这些数据划分为“18到25"、"26到35"、"35到60’以及“60以上’几个面元。要实现该功能.需要使用panda的cut函数:

In [154]: bins = [18, 25, 35, 60, 100]
In [155]: cats = pd.cut(ages, bins)
In [156]: cats
Out[156]:
Lategorlcal:
array([(18, 25], (18, 25], (18, 25), (25, 35], (18, 25], (18, 25],
(35, 60], (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]], dtype=object)
Levels (4): Index([(18, 25], (25, 35], (35, 60], (60, 100]], dtype=object)

实际上是先定义一个labels指明每个值分别位于哪个区间(labels),然后对区间进行替换显示(levels)

cats.labels
array([0, 0, 0, 1, 0, 0, 2, 1, 3, 2, 2, 1])
默认区间为左开右闭,可以通过pd.cut(ages, [18, 26, 36, 61, 100], right=False)来修改为左闭右开。这个labels负责最后的显示,所以
group names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
pd.cut(ages, bins, labels=group_names)
#最后就不再是输出(18, 25]这种,而是输出Youth,YoungAdult等

如果传入面元数量(分组数量),则会根据数据最小值和最大值计算等长面元。

#将一些均匀分布数据分为四组
data = np.randam.rand(20)
pd.cut(data, 4, precision=2)

qcut是类似cut的函数,但是qcut是使用的样本分位数,所以得到大小基本相等的面元。即每个面元,每个分组的数据数量基本相同。pd.qcut(data,4)即将数据均匀撒在四个分组中。

#当然也不一定每个分组的数据数量要相同
pd.qcut(data, [0, 0.1, 0.5, 0.9, 1."];
#就是按照1:4:4:1比例来分组。
检测和过滤异常值
#找出某列中绝对值大于3的值:
col=data[3]
col[np.abs(col)>3]
#选出所有含有超过3或-3的值的行,可以利用布尔型DataFrame以及any方法:
data[(np.abs(data) > 3).any(1)]
#将值限制在区间-3到3以内:(大于3的取3 小于-3的取-3)
data[np.abs(data) > 3] = np.sign(data) *3
#sign为取符号正数为1负数为-1 0为0
排列和随机采样
#reshape(5,4)分成5行4列
df = DataFrame(np.arange(5 * 4).reshape(5, 4))
#permutation(5)排列
sampler = np.random.permutation(5)
sampler: array((1, 0, 2, 3, 4])
df.take(sampler)
#即会把df的第1行和第0行互换排列
从permutation返回的数组中切下前3个元素
df.take(np.random.permutation(len(df))[:3])
#从一个数组里,随机取10个里面的值:
bag = np.array((S, 7, -1, 6, 4])
sampler = np.random.randint(0, len(bag), size=10)
sampler:
array([4, 4, 2, 2, 2, 0, 3, 0, 4, 1])
draws = bag.take(sampler)
draws:
array([ 4, 4, -1, -1, -1, 5, 6, 5, 4, 7])
计算指标/哑变量

DataFrame的某一列中含有k个不同的值,则可以派生出一个k列矩阵或DataFrame(其值全为1和0) .pandas有一个get _dummies函数可以实现该功能。

df = DataFrame({'key':['b', 'b', 'a', 'c', 'a','b'],'data1': range(6)})
pd.get_dummies(df['key'])
a b c
0 0 1 0
1 0 1 0
2 1 0 0
3 0 0 1
4 1 0 0
5 0 1 0

DataFrame列加上一个前缀,abc即变为key_a,key_b,key_c

dummies = pd.get_dummies(df['key']), prefix='key')
字符串操作

python能够成为流行的数据处理语言,部分原因是其简单易用的字符申和文本处理功能。大部分文本运算都直接做成了字符串对象的内置方法。对于更为复杂的模式匹配和

文本操作。则可能需要用到正则表达式。pandas对此进行了加强。它使你能够对整组数据应用字符串表达式和正则表达式.而且能处理烦人的缺失数据。

字符串对象方法
tags: data,np,数据,DataFrame,df,pd,two,map,key,cut
分页:12
转载请注明
本文标题:利用Python进行数据分析(十一)之数据规整化
本站链接:http://www.codesec.net/view/573764.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 挖掘分析应用 | 评论(0) | 阅读(261)