跟我一起学点 数据分析 -- 第三天:上手pandas(3)

前文回顾
DataFrame 核心分析方法
清洗数据
python中用NaN(Not a Number)表示缺失数据
先搞一波数据来看看:
df = pd.DataFrame([[1,5,8],[2,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
  
 - 1
 
 0 1 2
0  1.0  5.0  8.0
1  2.0  NaN  NaN
2  2.0  3.0  NaN
3  NaN  NaN  NaN
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
判断行列中是否有空数据
axis=0,代表列,axis=1代表行
查看行:df.isnull().any(axis=1)  
查看列:df.isnull().any(axis=0)
  
 - 1
 - 2
 
我弄了个按行判断的你们看一下:
0 False
1 True
2 True
3 True
dtype: bool
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
再看一下这个:
查看行:df.notnull().all(axis=1)
查看列:df.notnull().all(axis=0)
  
 - 1
 - 2
 
这个的话,只要有非空数据,就会被判断为True。
以上方法,都可以通过取反符号“~”来进行取反。
print(~df.isnull().any(axis = 1))
  
 - 1
 
也可以通过loc()方法来进行取值。
比方说我要取出所有非空数据行,可以这样来进行实现:
df = df.loc[~df.isnull().any(axis = 1)]
  
 - 1
 
 0 1 2
0  1.0  5.0  8.0
  
 - 1
 - 2
 
至于这个loc()方法,等会儿会说。
你也可以指定一列来进行空值的判断:
print(df[1].isnull())	# 判断一列的空值
print(df[1].isnull().value_counts())	# 对一列空值数量进行统计
  
 - 1
 - 2
 
清理行/列
相对来说有一个很直接的方法,直接将所有有空值的行、列进行清除:
df = pd.DataFrame([[1,5,8],[2,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
df = df.dropna()
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
不附加任何的额外条件,只要你那一行里面存在空值,一行清理。
 0 1 2
0  1.0  5.0  8.0
  
 - 1
 - 2
 
如果是要按列清理呢?那就加上:
df = pd.DataFrame([[1,5,8],[2,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
df = df.dropna(axis=1)
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
啊,很遗憾的告诉你,全部被清理了,一点不剩,因为每一列都有空值啊。。。
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3]
  
 - 1
 - 2
 - 3
 
好,那你现在跟我说,你觉得一行有那么一两个坏值其实是可以忍受的,那我怎么办?那我不还得给你办嘛:
# 只要有n个值是好的,就留下:
df = pd.DataFrame([[1,5,8],[np.nan,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
df = df.dropna(thresh=1)	# n
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 
 0 1 2
0  1.0  5.0  8.0
2  2.0  3.0  NaN
  
 - 1
 - 2
 - 3
 
对吧。那这要不是你想要的,那我也没办法了。
还有什么,删除指定列?删除指定行?那试试看嘛,摸索一下。
df = pd.DataFrame([[1,5,8],[np.nan,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
df = df.drop(labels=1)
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
 0 1 2
0  1.0  5.0  8.0
2  2.0  3.0  NaN
3  NaN  NaN  NaN
  
 - 1
 - 2
 - 3
 - 4
 
呐,我把那第一列删了。
神乎其技!!!
df = pd.DataFrame([[1,5,8],[np.nan,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
df = df.drop(columns=2)
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
不好意思,上面删的是一行,这里才是删一列。。。
 0 1
0  1.0  5.0
1  NaN  NaN
2  2.0  3.0
3  NaN  NaN
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
哎,且看且珍惜吧,我不知道还能发多少了。
去重
如果你拿到一个数据集,非常大,你感觉里面有不少重复值,想要进行一波去重操作,怎么办?
还有一个drop_duplicates还没看。
换个数据集玩玩吧,一直用那个也累了。
df = pd.DataFrame({'Country':[1,1,2,12,34,23,45,34,23,12,2,3,4,1], 'Income':[1,1,2,10000, 10000, 5000, 5002, 40000, 50000, 8000, 5000,3000,15666,1], 'Age':[1,1,2,50, 43, 34, 40, 25, 25, 45, 32,12,32,1], 'group':[1,1,2,'a','b','s','d','f','g','h','a','d','a',1]})
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 
 	Country  Income  Age group
0 1 1 1 1
1 1 1 1 1
2 2 2 2 2
3 12   10000   50 a
4 34   10000   43 b
5 23 5000   34 s
6 45 5002   40 d
7 34   40000   25 f
8 23   50000   25 g
9 12 8000   45 h
10 2 5000   32 a
11 3 3000   12 d
12 4   15666   32 a
13 1 1 1 1
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 
直接上手去重:
df.drop_duplicates(inplace=True)	#inplace=True 对原表进行修改
  
 - 1
 
 Country  Income  Age group
0 1 1 1 1
2 2 2 2 2
3 12   10000   50 a
4 34   10000   43 b
5 23 5000   34 s
6 45 5002   40 d
7 34   40000   25 f
8 23   50000   25 g
9 12 8000   45 h
10 2 5000   32 a
11 3 3000   12 d
12 4   15666   32 a
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 
少了一列啊。
大家看数据表中的索引,在我们使用drop_duplicates删除重复行时,重复行相对应的索引值也是被默认删除掉的,也就是说,索引值已经发生了变化。
那我们该如何解决这个问题呢?
df.drop_duplicates(inplace=True)
df = df.reset_index(drop=True)
print(df)
  
 - 1
 - 2
 - 3
 
	Country  Income  Age group
0 1 1 1 1
1 2 2 2 2
2 12   10000   50 a
3 34   10000   43 b
4 23 5000   34 s
5 45 5002   40 d
6 34   40000   25 f
7 23   50000   25 g
8 12 8000   45 h
9 2 5000   32 a
10 3 3000   12 d
11 4   15666   32 a
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 
如果要指定保留的重复行(默认是第一行),可以使用keep参数:一般没什么给你选的,要么就first,要么就last。
对指定的数据列进行去重:
df.drop_duplicates(inplace=True,subset = ['Age'],keep='last')
df = df.reset_index(drop=True)
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
0 2 2 2 2
1 12   10000   50 a
2 34   10000   43 b
3 23 5000   34 s
4 45 5002   40 d
5 23   50000   25 g
6 12 8000   45 h
7 3 3000   12 d
8 4   15666   32 a
9 1 1 1 1
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 
如果要多几行呢?
 这操作叫什么?思考一下数据库中的主键。
df.drop_duplicates(inplace=True,subset = ['Age','group'],keep='last')
df = df.reset_index(drop=True)
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
 Country  Income  Age group
0 2 2 2 2
1 12   10000   50 a
2 34   10000   43 b
3 23 5000   34 s
4 45 5002   40 d
5 34   40000   25 f
6 23   50000   25 g
7 12 8000   45 h
8 3 3000   12 d
9 4   15666   32 a
10 1 1 1 1
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 
清理讲到这里,接下来我们来填充缺失值。
填充缺失值
现在让我们把数据集换回去。
然后填充一下缺失值:
df = pd.DataFrame([[1,5,np.nan],[2,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
df = df.fillna(value=0)	# 以指定值对缺失值进行填补
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
 0 1 2
0  1.0  5.0  0.0
1  2.0  0.0  0.0
2  2.0  3.0  0.0
3  0.0  0.0  0.0
  
 - 1
 - 2
 - 3
 - 4
 - 5
 
用某一列的平均值对某一列进行填充:
df = pd.DataFrame([[1,5,np.nan],[2,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
print(df)
df[1] = df.fillna(df[1].mean())
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 
 0 1   2
0  1.0  5.0 NaN
1  2.0  NaN NaN
2  2.0  3.0 NaN
3  NaN  NaN NaN 0 1 2
0  1.0  5.0  1.0
1  2.0  NaN  2.0
2  2.0  3.0  2.0
3  NaN  NaN  NaN
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 
要不你试试第二列?
呐,不指定列试试看:
df = pd.DataFrame([[1,5,np.nan],[2,np.nan,np.nan],[2,3,np.nan],[np.nan,np.nan,np.nan]])
print(df)
df = df.fillna(df.mean())
print(df)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 
自上而下填充:
df = df.fillna(method='ffill')
print(df)
  
 - 1
 - 2
 - 3
 
 0 1   2
0  1.0  5.0 NaN
1  2.0  NaN NaN
2  2.0  3.0 NaN
3  NaN  NaN NaN 0 1   2
0  1.0  5.0 NaN
1  2.0  5.0 NaN
2  2.0  3.0 NaN
3  2.0  3.0 NaN
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 
有自上而下就有自下而上了:
df = df.fillna(method='bfill')
print(df)
  
 - 1
 - 2
 - 3
 
 0 1   2
0  1.0  5.0 NaN
1  2.0  NaN NaN
2  2.0  3.0 NaN
3  NaN  NaN NaN 0 1   2
0  1.0  5.0 NaN
1  2.0  3.0 NaN
2  2.0  3.0 NaN
3  NaN  NaN NaN
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 
再讲个小技巧,但是也是很让人烦恼的脏数据:空格
消除数据中的空格
# 创建含有空格的数据
dict1 = {"name": ["小红", "小明", "小张"], "age": [16, 17, 18], "city": ["北京  ", "杭州", "  上海  "]}
df2 = pd.DataFrame(dict1, columns=["name", "age", "city"])
print(df2)
# 清除空格
df2["city"] = df2["city"].map(str.strip)
print(df2)
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 
 name  age city
0   小红   16 北京  
1   小明   17 杭州
2   小张   18 上海 name  age  city
0   小红   16   北京
1   小明   17   杭州
2   小张   18   上海
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 
选择数据
pandas按列选择数据
就先来个最直观的方式,直接中括号取值。
# 创建含有空格的数据
dict1 = {"name": ["小红", "小明", "小张"], "age": [16, 17, 18], "city": ["北京  ", "杭州", "  上海  "]}
df2 = pd.DataFrame(dict1, columns=["name", "age", "city"])
# 清除空格
df2["city"] = df2["city"].map(str.strip)
print(df2['name'])
  
 - 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 
0 小红
1 小明
2 小张
Name: name, dtype: object
  
 - 1
 - 2
 - 3
 - 4
 
当然,你要是不知道列名称那怎么行?连列名都不知道还取个球。。。
print(df2.columns)
  
 - 1
 
酱紫
Index(['name', 'age', 'city'], dtype='object')
  
 - 1
 
一般都要选择多列数据的,对吧,对吧!
行,我们来选取一下多列数据:
print(df2[['name','age']])	# 看清楚,传进去的是一个列表,而不是两个字符串咯。
  
 - 1
 
 name  age
0   小红   16
1   小明   17
2   小张   18
  
 - 1
 - 2
 - 3
 - 4
 
按照数据类型选择列
先来获取一下当前DataFrame的数据列数据类型情况吧:
name object
age int64
city object
dtype: object
  
 - 1
 - 2
 - 3
 - 4
 
获取一下object对象呗:
print(df2.select_dtypes(include='object'))
  
 - 1
 
  	name  city
0   小红   北京
1   小明   杭州
2   小张   上海
  
 - 1
 - 2
 - 3
 - 4
 
那,如果说我要选择‘object’对象以外的对象呢?
print(df2.select_dtypes(exclude='object'))
  
 - 1
 
   age
0   16
1   17
2   18
  
 - 1
 - 2
 - 3
 - 4
 
filter方法选择列
它有三个常用参数,我们一个一个看,不过要注意:这三个参数并不能同时出现。
使用items选择多个列:
df2 = df2.filter(items=['name','age'])
print(df2)
  
 - 1
 - 2
 - 3
 
就跟上面那个直接取值的是一样的。
  name  age
0   小红   16
1   小明   17
2   小张   18
  
 - 1
 - 2
 - 3
 - 4
 
使用like选择匹配的列:要求列名中含有。。。
df2 = df2.filter(like='a')
print(df2)
  
 - 1
 - 2
 - 3
 
  	name  age
0   小红   16
1   小明   17
2   小张   18
  
 - 1
 - 2
 - 3
 - 4
 
使用正则表达式取列:
df2 = df2.filter(regex='[a-z]')
print(df2)
  
 - 1
 - 2
 - 3
 
  	name  age  city
0   小红   16   北京
1   小明   17   杭州
2   小张   18   上海
  
 - 1
 - 2
 - 3
 - 4
 
pandas按行选择数据
先看个loc方法啊:
df2 = df2.loc[0:2]
print(df2)
  
 - 1
 - 2
 - 3
 
  	name  age city
0   小红   16   北京
1   小明   17   杭州
2   小张   18   上海
  
 - 1
 - 2
 - 3
 - 4
 
你悟到了?
再来:
df2 = df2.loc[0:2,['name','age']]
  
 - 1
 
  	name  age
0   小红   16
1   小明   17
2   小张   18
  
 - 1
 - 2
 - 3
 - 4
 
我就把结果放这儿,我就默默不说话。
df2 = df2.loc[(df2['age']>16) & (df2['age']<18)]
df2 = df2.loc[(df2['age']>16) | (df2['age']<18)]
  
 - 1
 - 2
 
这里我连结果都不想放了,发挥你们的想象力。
差不多了吧,我想想还有啥、、
lambda表达式,对、
df2 = df2.loc[lambda x:x.city == '北京']
  
 - 1
 
呐,像这样。
如果不出意外,这篇就到这里啦,see you!!!
 
文章来源: blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_43762191/article/details/111866076
- 点赞
 - 收藏
 - 关注作者
 
            
           
评论(0)