概述
'''5.2.1 删除重复值'''
# data = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'],
#
'k2': [1, 1, 2, 3, 3, 4, 4]})
'''DataFrame的duplicated方法返回的是一个布尔值Series,这个Series反映的是每一行是否存在重复情况:'''
# print(data.duplicated())
'''
0
False
1
False
2
False
3
False
4
False
5
False
6
True
dtype: bool'''
'''drop_duplicated返回的是DataFrame,内容是duplicated返回数组中为False的部分:'''
# print(data.drop_duplicates())
'''
k1
k2
0
one
1
1
two
1
2
one
2
3
two
3
4
one
3
5
two
4'''
'''这些方法都是对列进行操作。你可以指定数据的任何子集来检测是否有重复。假设我们有一个额外的列,并想基于'k1'列去除重复值:'''
# data['v1'] = range(7)
# print(data.drop_duplicates(['k1']))
'''
k1
k2
v1
0
one
1
0
1
two
1
1'''
'''duplicated和drop_duplicates默认都是保留第一个观测到的值。传入参数keep='last'将会返回最后一个:'''
# print(data.drop_duplicates(['k1', 'k2'], keep='last'))
'''
k1
k2
v1
0
one
1
0
1
two
1
1
2
one
2
2
3
two
3
3
4
one
3
4
6
two
4
6'''
'''训练:获取清单中不重复的套餐名称列表:'''
# data = pd.read_table(r"C:UsersAdministratorDesktop报表数据cdma.xls", engine='python')
# data2 = data.drop_duplicates(['套餐名称'])['套餐名称']
# print(data2)
'''5.2.2 使用函数或映射进行数据转换(相当于数据匹配vlookup,当然后面有更好的方法):'''
'''对于许多数据集,可能需要基于DataFrame中的数组、列或列中的数值进行一些转换。考虑下面这些收集到的关于肉类的假设数据:'''
data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
'Pastrami', 'corned beef', 'Bacon',
'pastrami', 'honey ham', 'nova lox'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
'''假设想要添加一列用于表明每种食物的动物肉类型。让我们先写下一个食物和肉类的映射:'''
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}
'''Series的map方法接收一个函数或一个包含映射关系的字典型对象,但是这里我们有一个小的问题在于一些肉类大些了,而另一部分肉类没有。
因此,我们需要使用Series的str.lower方法将每个值都转换为小写:'''
# lowercased = data['food'].str.lower()
# data['animal'] = lowercased.map(meat_to_animal)
# print(data)
'''
food
ounces
animal
0
bacon
4.0
pig
1
pulled pork
3.0
pig
2
bacon
12.0
pig
3
Pastrami
6.0
cow
4
corned beef
7.5
cow
5
Bacon
8.0
pig
6
pastrami
3.0
cow
7
honey ham
5.0
pig
8
nova lox
6.0
salmon'''
'''也可以传入一个能够完成所有工作的函数,使用map是一种可以便捷执行按元素转换及其他清洗相关操作的方法:'''
# data['animal'] = data['food'].map(lambda x: meat_to_animal[x.lower()])
# print(data)
'''5.2.3 替代值'''
'''使用fillna填充缺失值是通用值替换的特殊案例。map可以用来修改一个对象中的子集的值,但是replace提供了更为简单灵活的实现。'''
# data = pd.Series([1., -999., 2., -999., -1000., 3.])
'''-999可能是缺失值的标识。如果要使用NA来替代这些值,可以使用replace方法生成新的Series(除非你传入了inplace=True):'''
# print(data.replace(-999, np.nan))
'''
0
1.0
1
NaN
2
2.0
3
NaN
4
-1000.0
5
3.0
dtype: float64'''
'''如果想要一次替换多个值,可以传入一个列表和替代值:'''
# print(data.replace([-999, -1000], np.nan))
'''要将不同的值替换为不同的值,可以传入替代值的列表:'''
# print(data.replace([-999, -1000], [np.nan, 0]))
'''参数也可以通过字典传递:'''
# print(data.replace({-999: np.nan, -1000:0}))
'''Tip:data.replace方法与data.str.replace方法是不同的,data.str.replace是对字符串进行按元素替代的。'''
'''5.2.4 重命名轴索引'''
'''和Series中的值一样,可以通过函数或某种形式的映射对轴标签进行类似的转换,生成新的且带有不同标签的对象。
你也可以在不生成新的数据结构的情况下修改轴。'''
# data = pd.DataFrame(np.arange(12).reshape((3, 4)),
#
index=['Ohio', 'Colorado', 'New York'],
#
columns=['one', 'two', 'three', 'four'])
# print(data)
# transform = lambda x: x[:4].upper()
# print(data.index.map(transform)) #Index(['OHIO', 'COLO', 'NEW '], dtype='object')
'''可以赋值给index,修改DataFrame:'''
# data.index = data.index.map(transform)
# print(data)
'''
one
two
three
four
OHIO
0
1
2
3
COLO
4
5
6
7
NEW
8
9
10
11'''
'''如果想要创建数据集转换后的版本,并且不修改原有的数据集,一个有用的方法是rename:'''
# print(data.rename(index=str.title, columns=str.upper))
'''
ONE
TWO
THREE
FOUR
Ohio
0
1
2
3
Colo
4
5
6
7
New
8
9
10
11'''
'''需要注意的是,rename可以结合字典型对象使用,为轴标签的子集提供新的值:'''
# print(data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}))
'''
one
two
peekaboo
four
INDIANA
0
1
2
3
COLO
4
5
6
7
NEW
8
9
10
11'''
'''rename可以让你从手动复制DataFrame并为其分配索引和列属性的繁琐工作中解放出来。如果想要修改原有的数据集,传入inplace=True'''
# data.rename(index={'OHIO': 'INDIANA'}, inplace=True)
# print(data)
'''
one
two
three
four
INDIANA
0
1
2
3
COLO
4
5
6
7
NEW
8
9
10
11'''
'''5.2.5 离散化和分箱'''
'''连续值经常需要离散化,或者分离成“箱子”进行分析。假设你有某项研究中一组人群的数据,想将他们进行分组,放入离散的年龄框中:'''
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
'''让我们将这些年龄分为18~25、26~35、36~60以及61及以上等若干组。pandas中的cut可以实现:'''
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages, bins)
# print(cats)
'''
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]'''
'''pandas返回的对象是一个特殊的Categorical对象。你看到的输出描述了由pandas.cut计算出的箱。你可以将他当做一个表示箱名的字符串数组;
它在内部包含一个categories(类别)数组,它指定了不同的类别名称以及codes属性中的ages(年龄)数据标签:'''
# print(cats.codes) #[0 0 0 1 0 0 2 1 3 2 2 1]
# print(cats.categories)
'''
IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]]
closed='right',
dtype='interval[int64]')'''
# print(pd.value_counts(cats))
'''
(18, 25]
5
(35, 60]
3
(25, 35]
3
(60, 100]
1
dtype: int64'''
'''请注意,pd.value_counts(cats)是对panas.cut的结果中的箱数量的计数。
与区间的数学符号一致,小括号表示边是开放的,中括号表示它是封闭的(包括边)。你可以通过传递right=False来改变哪一边是封闭的:'''
# print(pd.cut(ages, [18, 26, 36, 61, 100], right=False))
'''
[[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), ..., [26, 36), [61, 100), [36, 61), [36, 61), [26, 36)]
Length: 12
Categories (4, interval[int64]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)]'''
'''也可以通过向labels选项传递一个列表或数组来传入自定义的箱名:'''
# group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
# print(pd.cut(ages, bins, labels=group_names))
'''
[Youth, Youth, Youth, YoungAdult, Youth, ..., YoungAdult, Senior, MiddleAged, MiddleAged, YoungAdult]
Length: 12
Categories (4, object): [Youth < YoungAdult < MiddleAged < Senior]'''
'''如果你传给cut整数个的箱来代替显式的箱边,pandas将根据数据中的最小值和最大值计算出等长的箱。请考虑一些均匀分布的数据被切成四份的情况:'''
# data = np.random.rand(20)
# print(pd.cut(data, 4, precision=2))
'''precision=2的选项将十进制精度限制在两位:
[(0.27, 0.5], (0.039, 0.27], (0.039, 0.27], (0.73, 0.96], (0.5, 0.73], ..., (0.039, 0.27], (0.039, 0.27], (0.27, 0.5], (0.5, 0.73], (0.5, 0.73]]
Length: 20
Categories (4, interval[float64]): [(0.039, 0.27] < (0.27, 0.5] < (0.5, 0.73] < (0.73, 0.96]]'''
'''qcut是一个与分箱密切相关的函数,它基于样本分位数进行分箱。取决于数据的分布,使用cut通常不会使每个箱具有相同数据量的数据点。
由于qcut使用样本的分位数,可以通过qcut获得等长的箱:'''
data = np.random.randn(1000) #正态分布
cats = pd.qcut(data, 4) #切成四份
# print(pd.value_counts(cats))
'''
(0.715, 3.641]
250
(-0.0151, 0.715]
250
(-0.713, -0.0151]
250
(-3.143, -0.713]
250
dtype: int64'''
'''与cut类似,你可以传入自定义的分位数(0和1之间的数据,包括边):'''
# print(pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.]))
'''5.2.6 检测和过滤异常值'''
data = pd.DataFrame(np.random.randn(1000, 4))
# print(data.describe())
'''假设想要找出一列中绝对值大于三的值:'''
col = data[2]
# print(col[np.abs(col) > 3])
'''
403
3.097313
687
-3.073907
Name: 2, dtype: float64'''
'''要找出所有值大于3或小于-3的行,可以对布尔值DataFrame使用any方法:'''
# print(data[(np.abs(data) > 3).any(1)])
'''
0
1
2
3
117
0.443424 -3.362000
0.868803
0.934487
166 -3.182563
0.810675
0.151707
0.141465
340
3.198421
0.253272 -0.282828 -0.863665
488 -3.195636 -1.981028 -0.150848
0.292874
603
0.418023 -0.300602
3.033932
0.853207
604
2.217083
3.763026 -0.433097
0.049302
663 -1.447432 -0.826053
0.060816 -3.106095
721
0.972289
0.679467
2.766050
3.215147
837 -0.363630
0.008714 -1.708609 -3.074064
860
1.050260
0.208776
0.631330 -3.069116
973 -3.176069 -0.526400
0.007942
2.222808'''
'''值可以根据这些标准来设置,下列代码限制了-3到3之间的数值:'''
data[np.abs(data) > 3] = np.sign(data) * 3
# print(data.describe())
'''
0
1
2
3
count
1000.000000
1000.000000
1000.000000
1000.000000
mean
0.023728
0.024702
0.016806
-0.012628
std
0.979471
0.990950
0.984842
1.012999
min
-3.000000
-3.000000
-2.981538
-3.000000
25%
-0.613863
-0.651061
-0.646219
-0.691173
50%
0.019730
0.033089
-0.003635
-0.009341
75%
0.699006
0.705962
0.655847
0.653943
max
3.000000
3.000000
3.000000
3.000000'''
'''语句np.sign(data)根据数据中的值的正负分别生成1和-1的数值'''
# print(np.sign(data).head())
'''
0
1
2
3
0
1.0
1.0
1.0
1.0
1 -1.0
1.0
1.0
1.0
2
1.0
1.0
1.0 -1.0
3
1.0
1.0
1.0
1.0
4
1.0 -1.0
1.0 -1.0'''
'''5.2.7 置换和随机抽样'''
'''使用numpy.random.permutation对DataFrame中的Series或行进行置换(随机重排序)是非常方便的。
在调用permutation时根据你想要的轴长度可以产生一个表示新顺序的整数数组:'''
df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4)))
# print(df)
'''
0
1
2
3
0
0
1
2
3
1
4
5
6
7
2
8
9
10
11
3
12
13
14
15
4
16
17
18
19'''
sampler = np.random.permutation(5)
# print(sampler) #[2 1 4 0 3]
'''整数数组可以用在基于iloc的索引或等价的take函数中:'''
# print(df.take(sampler))
'''
0
1
2
3
2
8
9
10
11
1
4
5
6
7
4
16
17
18
19
0
0
1
2
3
3
12
13
14
15'''
'''要选出一个不含有替代值的随机子集,可以使用Series和DataFrame的sample方法:'''
# print(df.sample(n=3))
'''下面的子集是随机变动的,只要有3行就行
0
1
2
3
1
4
5
6
7
3
12
13
14
15
4
16
17
18
19'''
'''要生成一个带有替代值的样本(允许有重复选项),将replace=True传入sample方法:'''
choices = pd.Series([5, 7, -1, 6, 4])
draws = choices.sample(n=10, replace=True)
# print(draws)
'''
1
7
4
4
2
-1
0
5
3
6
2
-1
1
7
1
7
0
5
4
4
dtype: int64'''
'''5.2.8 计算指标/虚拟变量'''
'''将分类变量转换为“虚拟”或“指标”矩阵是另一种用于统计建模或机器学习的转换操作。
如果DataFrame中的一列有k个不同的值,则可以衍生一个k列的值为1和0的矩阵或DataFrame。pandas有一个get_dummies函数用于实现该功能'''
df = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
'data1': range(6)})
# print(df)
'''
key
data1
0
b
0
1
b
1
2
a
2
3
c
3
4
a
4
5
b
5'''
# print(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的列上加入前缀,然后与其他数据合并。在get_dummies方法中有一个前缀参数用于实现该功能:'''
dummies = pd.get_dummies(df['key'], prefix='key')
df_with_dummpy = df[['data1']].join(dummies)
# print(df_with_dummpy)
'''
data1
key_a
key_b
key_c
0
0
0
1
0
1
1
0
1
0
2
2
1
0
0
3
3
0
0
1
4
4
1
0
0
5
5
0
1
0'''
最后
以上就是坚定御姐为你收集整理的Pandas学习(5.2、数据清洗与准备)的全部内容,希望文章能够帮你解决Pandas学习(5.2、数据清洗与准备)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复