DataFrame基本操作 <三> 计算名次,移除重复数据,数据替换,划分区间,分组统计(变成类)
生成一个实例
df5 = DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1], 'c': [-2, 5, 8, -2.5]}) print(df5)
运行结果
b a c
0 4.3 0 -2.0
1 7.0 1 5.0
2 -3.0 0 8.0
3 2.0 1 -2.5
计算名次
print(df5.rank() ) # 按行计算名次 print(df5.rank(axis=1)) # 按列计算名次 #这有意思了,这是计算名次,显示的结果是名次,不是里边值的内容,只能用在f类型,df5.rank()是垂直方向比大小,竖着四个谁最大,显示的数字最大,最大4,最小1 #df5.rank(axis=1)就是水平方向比大小,三个 数字之间比,最大3,最小1
运行结果
b a c 0 4.3 0 -2.0 1 7.0 1 5.0 2 -3.0 0 8.0 3 2.0 1 -2.5 #原本 b a c 0 3.0 1.5 2.0 1 4.0 3.5 3.0 2 1.0 1.5 4.0 3 2.0 3.5 1.0 #竖着比,也就是垂直比,4个值 b a c 0 3.0 2.0 1.0 1 3.0 1.0 2.0 2 1.0 2.0 3.0 3 3.0 2.0 1.0 #水平比,3个值
重新生成一个实例,观察这个实例的生成方法
df6 = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'], 'k2': [1, 1, 2, 3, 3, 4, 4]}) print(df6) df7 = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'], 'k2': list('1123344')}) print(df6) print(df7) #以上两种方法,效果一样,但是结果不一样。。怎么理解那,上边的k2是int,下边的k2是str,我一开始错误的以为一样了,现在我们拿df6来举例
运行结果
k1 k2 0 one 1 1 two 1 2 one 2 3 two 3 4 one 3 5 two 4 6 two 4 #就写一个行了
移除重复的数据
print(df6.drop_duplicates()) # 移除重复的行 print(df6.drop_duplicates(['k1'])) # 移除某列有重复的行 print(df6[::-1].drop_duplicates(['k1'])) # 反向移除 #这里讲究了,第一个是垂直移除,移除的条件是同时满足k1,k2的值都相等 #第二个是k1列只有重复的都移除 #第三个是垂直反向开始
运行结果
k1 k2 0 one 1 1 two 1 2 one 2 3 two 3 4 one 3 5 two 4 6 two 4 #原版 k1 k2 0 one 1 1 two 1 2 one 2 3 two 3 4 one 3 5 two 4 #移除了重复的行‘two 4’ k1 k2 0 one 1 1 two 1 #k1 去掉重复的 k1 k2 6 two 4 4 one 3 #反向开始 去掉k1重复的
数据替换
这里是根据‘name’(cols)替换的。
我觉得这个方法挺重要的以后能用的上,挺好的。
i={k1[0]:123,k1[1:456}
df['name].map(i) #
k3 = {'one': 2001, 'two': 2002} df6['k3'] = df6['k1'].map(k3) # 根据已有的键值做转换 print(df6['k3']) print(df6) print(df6['k2'].replace([2, 4], 0)) # 替换特定的值 print(df6) #第一个,k1里边有‘one’,‘two’,创建k3,用map方法 #第二个就是字面意思,k2里边的2,4替换成0
运行结果
k1 k2 0 one 1 1 two 1 2 one 2 3 two 3 4 one 3 5 two 4 6 two 4 #原版 0 2001 1 2002 2 2001 3 2002 4 2001 5 2002 6 2002 Name: k3, dtype: int64 #k3的数据 k1 k2 k3 0 one 1 2001 1 two 1 2002 2 one 2 2001 3 two 3 2002 4 one 3 2001 5 two 4 2002 6 two 4 2002 #现版 0 1 1 1 2 0 3 3 4 3 5 0 6 0 Name: k2, dtype: int64 #替换后的k2 k1 k2 k3 0 one 1 2001 1 two 1 2002 2 one 2 2001 3 two 3 2002 4 one 3 2001 5 two 4 2002 6 two 4 2002 #请注意!!!这里如果你打印df6,还是上一版,k2的新值没有赋过来,也就是replace返回的结果是单独的。
那么如何将新产生的k2赋值给df6
a=df6['k2'].replace([2, 4], 0) df6['k2']=a print(df6)
运行结果
k1 k2 k3 0 one 1 2001 1 two 1 2002 2 one 0 2001 3 two 3 2002 4 one 3 2001 5 two 0 2002 6 two 0 2002 完美
划分区间
对零散是数据划分区间
bins = pd.cut(df6['k2'], [0, 2, 4]) # 对离散数据划分区间,cut用法,划分两个区间,0~2,2~4 print(bins) df6['k2']=bins print(df6)
运行结果
k1 k2 0 one 1 1 two 1 2 one 2 3 two 3 4 one 3 5 two 4 6 two 4 #原版 0 (0, 2] 1 (0, 2] 2 (0, 2] 3 (2, 4] 4 (2, 4] 5 (2, 4] 6 (2, 4] Name: k2, dtype: category Categories (2, interval[int64]): [(0, 2] < (2, 4]] #这里区间的意思是0~2之间的划为一块,2~4之间的划为一块 k1 k2 0 one (0, 2] #1 1 two (0, 2] #1 2 one (0, 2] #2 3 two (2, 4] #3 4 one (2, 4] #3 5 two (2, 4] #4 6 two (2, 4] #4
同理,再来一个对比
bins = pd.cut(df6['k2'], [0, 3, 4]) # 对离散数据划分区间,cut用法,划分两个区间,0~3,3~4 print(bins) df6['k2']=bins print(df6)
运行结果
k1 k2 0 one (0, 3] 1 two (0, 3] 2 one (0, 3] 3 two (0, 3] 4 one (0, 3] 5 two (3, 4] 6 two (3, 4]
按区间对离散数值进行统计
bins = pd.cut(df6['k2'], [0, 2, 4]) # 对离散数据划分区间,cut用法,划分两个区间,0~2,2~4 print(pd.value_counts(bins)) # 按区间对离散值统计
运行结果
(2, 4] 4 (0, 2] 3 Name: k2, dtype: int64
生成新的‘name’,加上分类信息
bins = pd.cut(df6['k2'], [0, 2, 4]) # 对离散数据划分区间,cut用法,划分两个区间,0~2,2~4 df6['k3'] = bins # 在原有dataframe上直接加上分类信息,这里生成了k3 print(df6)
运行结果
k1 k2 k3 0 one 1 (0, 2] 1 two 1 (0, 2] 2 one 2 (0, 2] 3 two 3 (2, 4] 4 one 3 (2, 4] 5 two 4 (2, 4] 6 two 4 (2, 4]
分组统计
group_6=df6.groupby([df6['k3']]) # 分组,好像创建了一个类。。。。这里如果是k2或者k1,无法使用统计平均数,mean是个类的方法。 这里是整个表。。。下边的练习是一串数字 print(group_6.sum()) # 统计 求和 print(group_6.mean()) # 统计 平均数 这个平均数是k2的!!!这就是个类,没错就是把整个df6变成一个类了
运行结果
k1 k2 k3 0 one 1 (0, 2] 1 two 1 (0, 2] 2 one 2 (0, 2] 3 two 3 (2, 4] 4 one 3 (2, 4] 5 two 4 (2, 4] 6 two 4 (2, 4] k2 k3 (0, 2] 4 #加一起的和?? 这里应该还是说的k3,不是指的k2,我以前理解有问题 (2, 4] 14 k2 k3 (0, 2] 1.333333 (2, 4] 3.500000
# group_6.apply(function_name) # 对分组对象应用自定义函数 # 练习: 对df6按k3分组后,求每组中k2列的最大值和最小值 # 要求利用 apply 函数
这个作业看着很简单,但是我理解起来挺吃力的。
这个答案不是我写的,实在是不好下口,因为理解的不到位,没有切入点吧...不知道为啥这个这么吃力
df6 = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'], 'k2': [1, 1, 2, 3, 3, 4, 4]}) bins = pd.cut(df6['k2'], [0, 2, 4], labels=['Low', 'High']) #还是用0~2,2~4分开,但是标签用low跟high df6['k3'] = bins # group_6 = df6['k2'].groupby(df6['k3']) #这是懵逼,我的理解是df6['k2]这一串数字进行group化统计,用k3里的low与hig分成2组 print(group_6.max(),'我是max') #打印了一下看了看 k3 # Low 2 #low里边最大的 # High 4 #high里边最大的 # Name: k2, dtype: int64 我是max print(group_6.min(),'我是min') ##打印了一下看了看 k3 # Low 1 #low里边最小的 # High 3 #high里边最小的 # Name: k2, dtype: int64 我是min def myfunc(g): #这里也能看懂,就是传入一个group(分组统计的类) return {'Max': g.max(), 'Min': g.min()} #以字典的形势返回 print(group_6.apply(myfunc)) #group_适用于后边的函数表达式
运行结果
k3 Low 2 High 4 Name: k2, dtype: int64 我是max k3 Low 1 High 3 Name: k2, dtype: int64 我是min k3 Low Max 2 Min 1 High Max 4 Min 3 Name: k2, dtype: int64