title: Pandas使用操作指南
subtitle: Pandas使用操作指南
date: 2020-12-22
author: NSX
catalog: true
tags:
- Pandas


数据帧介绍:

  1. 数据帧(DataFrame)是二维数据结构,即数据以行和列的表格方式排列。
  2. 数据帧(DataFrame)的功能特点:潜在的列是不同的类型大小可变标记轴(行和列)可以对行和列执行算术运算

pandas中的DataFrame可以使用以下构造函数创建:

参数 描述
data 数据采取各种形式,如:ndarray,series,map,lists,dict,constant和另一个DataFrame
index 对于行标签,要用于结果帧的索引是可选缺省值np.arrange(n)
columns 列标签
dtype 每列的数据类型。

常见使用操作汇总

DataFrame对象

创建

  1. # 通过列表创建
  2. data = [1,2,3,4,5]
  3. df = pd.DataFrame(data)
  4. data = [['Alex',10],['Bob',12],['Clarke',13]]
  5. df = pd.DataFrame(data,columns=['Name','Age'])
  6. # 从ndarrays/Lists的字典来创建
  7. data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
  8. df = pd.DataFrame(data, index=['rank1','rank2','rank3','rank4'])
  9. # 从列表创建数据帧DataFrame
  10. data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
  11. df = pd.DataFrame(data)
  12. # 从系列的字典来创建
  13. d = {'one' : pd.Series([1, 2, 3], index=[0,1,2]),
  14. 'two' : pd.Series([1, 2, 3, 4], index=[0,1,2,3])}
  15. df = pd.DataFrame(d)
  16. df

查看

  1. # 查看行数和列数
  2. print(df.shape)
  3. # 查看前n行
  4. print(df.head(5))
  5. # 查看后n行
  6. print(df.tail(5))
  7. # 查看数值型列的汇总统计
  8. print(df.describe())
  9. # 查看列名
  10. df.columns
  11. print(df._stat_axis.values.tolist()) # 行名称
  12. print(df.columns.values.tolist())
  13. # 某一列的列值
  14. df['one']
  15. # 第i行的第j列
  16. print(df.loc[0, "one"]) # 第1行的one列值
  17. print(df.iloc[0, 0]) # 第1行的第一列值,同上
  18. # 多行中的多列
  19. print(df.loc[[2,3],['one','two']]) #选取指定的第2行和第3行,name和age列的数据
  20. print(df.iloc[[2,3], [0,1]]) # 同上

修改

  1. # 列添加
  2. df['three']=pd.Series([10,20,30],index=['a','b','c'])
  3. df['four']=df['one']+df['two']
  4. print (df)
  5. # 列删除
  6. df.pop('two')
  7. print (df)
  8. # 行遍历&切片
  9. print(df[1:3])
  10. for index, row in df.iterrows(): # 第一行的值
  11. print(row)
  12. # 附加行
  13. df2 = pd.DataFrame([[5, 6], [7, 8]], columns=['one', 'two'])
  14. df = df.append(df2)
  15. print (df)
  16. # 删除行
  17. df = df.drop(0)
  18. print (df)

数据处理利器:map

  1. #②使用函数
  2. def gender_map(x):
  3. gender = 1 if x == "男" else 0
  4. return gender
  5. #注意这里传入的是函数名,不带括号
  6. data["gender"] = data["gender"].map(gender_map)

数据处理利器:apply

可以接收各种各样的函数(Python内置的或自定义的),也可以同时处理多列数据;

axis=0代表操作对列columns进行,axis=1代表操作对行row进行

  1. def BMI(series):
  2. weight = series["weight"]
  3. height = series["height"]/100
  4. BMI = weight/height**2
  5. return BMI
  6. # 沿着1轴操作
  7. data["BMI"] = data.apply(BMI,axis=1)

apply()在运算时实际上是一行一行遍历的,IO开销比较大,可以使用progress_apply()监视运行进度;

  1. def xx(a):
  2. return a+1
  3. print(type(data[['height', 'weight']]))
  4. data[['height', 'weight']] = data[['height', 'weight']].progress_apply(xx, axis=1)
  5. data

数据处理利器:applymap

applymap() 是与map() 方法相对应的专属于Dataframe对象的方法,可传入函数、字典等,作用于整个数据框中的每个位置的元素,返回结果的形状与元数据框 一致!

  1. def lowerx(x):
  2. if isinstance(x, str):
  3. return x.lower() + '_'
  4. else:
  5. return x
  6. data.applymap(lowerx)

过滤空值

常用于解决某行或某列值为NaN(空)的情况,很多时候我们要把这部分数据剔除,便于进一步的数据处理。

NaN由numpy产生,所以用python里的None无法判断pandas dataframe里的数据是否为空。本质上NaN不等于任何值,pandas的提供了相应的内置方法来处理该问题,如isnull(),notnull()

# 获取字段column1值不为空的数据库集 df = df[df['column1'].notnull()] # 获取字段column1值为空的数据库集 df = df[df['column1'].isnull()]

常见数据过滤操作

通过比较值过滤

# 获取某列等于某值的数据集 df.loc[df['column_name'] == some_value] # 某列不等于某值的数据集 df.loc[df['column_name'] != some_value] # 某列的值属于某个迭代器的子值,如python "target is in ["v1", "v2", "v3"] df.loc[df['column_name'].isin(["value1", "value2", "value3"])] # 多个过滤条件,使用 & 连接 df.loc[(df['column_name'] >= A) & (df['column_name'] <= B)] # 一定要注意带圆括号,因为&离A更近 # df['column_name'] >= A & df['column_name'] <= B 等同于df['column_name'] >= (A & df['column_name']) <= B # 否定条件(反条件),使用波浪号 "~",不建议使用减号 "-",减号在某些场合会失效 df.loc[~df['column_name'] == some_value] df.loc[~df['column_name'].isin(some_values)]

以……开始或以……结尾,语法与python标准库str对应的方法相同

>>> s = pd.Series(['bat', 'Bear', 'cat', np.nan]) >>> s 0 bat 1 Bear 2 cat 3 NaN dtype: object # 单值 >>> s.str.startswith('b') 0 True 1 False 2 False 3 NaN dtype: object >>> s.str.endswith('t') 0 True 1 False 2 True 3 NaN dtype: object # 多值,使用元组 >>> s.str.startswith(('b', 'c')) 0 True 1 False 2 True 3 NaN dtype: object

子字符串过滤,包含某值

# 初始化 df1 = pd.DataFrame({'col': ['foo', 'foobar', 'bar', 'baz', 'FOo']}) df1 col 0 foo 1 foobar 2 bar 3 baz # 正则过滤,查找某列的值含有foo但不以foo结尾的 df1[df1['col'].str.contains(r'foo(?!$)')] col 1 foobar # 非正则过滤,regex默认为True,即默认使用正则 df1[df1['col'].str.contains('foo', regex=False)] # same as df1[df1['col'].str.contains('foo')] but faster. col 0 foo 1 foobar # 忽略大小写,case默认为True,即默认大小写敏感 df1[df1['col'].str.contains('foo', regex=False, case=False)] col 0 foo 1 foobar 4 FOo

计算某列某个值出现的次数

使用 shape 或 len

print df col1 education 0 a 9th 1 b 9th 2 c 8th print df.education == '9th' 0 True 1 True 2 False Name: education, dtype: bool print df[df.education == '9th'] col1 education 0 a 9th 1 b 9th print df[df.education == '9th'].shape[0] 2 print len(df[df['education'] == '9th']) 2

获取某列的所有值

使用tolist()或values.tolist()

import pandas as pd df = pd.DataFrame({'a':[1,3,5,7,4,5,6,4,7,8,9], 'b':[3,5,6,2,4,6,7,8,7,8,9]}) >>> df['a'].tolist() [1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9] >>> df['a'].values.tolist() [1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9] # 剔除重复项,使用drop_duplicates或set >>> df['a'].drop_duplicates().values.tolist() [1, 3, 5, 7, 4, 6, 8, 9] >>> list(set(df['a'])) # as pointed out by EdChum [1, 3, 4, 5, 6, 7, 8, 9]

基于其他列生成新的列

使用apply方法映射处理数据的函数(操作类似map),同时注意axis=1的设置(按行处理)

data = [ {'ip': '128.0.0.1', 'name': 'abc', "request_time": "2019-07-04T01:04:23+08:00", 'request_body': 'username=qwer&fqwer'}, {'ip': '128.0.0.1', 'name': 'c', "request_time": "2019-07-04T00:04:23+08:00", 'request_body': 'pwd=qwer&fqwer'}, {'ip': '128.0.0.1', "request_time": "2019-07-04T07:04:23+08:00", 'name': 'abc', 'request_body': 'pwd=qwer&fqwer'}, {'ip': '128.0.0.2', 'name': 'e', "request_time": "2019-07-04T08:04:23+08:00", 'request_body': 'pwd=qwer&fqwer'}, {'ip': '128.0.0.2', 'name': 'e', "request_time": "2019-07-04T12:04:23+08:00", 'request_body': 'username=qwer&fqwer'}, {'ip': '128.0.0.3', 'name': 'g', "request_time": "2019-07-04T02:04:23+08:00", 'request_body': 'username=qwer&fqwer'} ] def check_user(row): if 'name' in row['request_body']: return 1 else: return 0 df = pd.DataFrame(data) new_df = df.copy() new_df.loc[:, 'hit_user'] = df.apply(lambda row: check_user(row), axis=1) print(new_df) ip name request_body request_time hit_user 0 128.0.0.1 abc username=qwer&fqwer 2019-07-04T01:04:23+08:00 1 1 128.0.0.1 c pwd=qwer&fqwer 2019-07-04T00:04:23+08:00 0 2 128.0.0.1 abc pwd=qwer&fqwer 2019-07-04T07:04:23+08:00 0 3 128.0.0.2 e pwd=qwer&fqwer 2019-07-04T08:04:23+08:00 0 4 128.0.0.2 e username=qwer&fqwer 2019-07-04T12:04:23+08:00 1 5 128.0.0.3 g username=qwer&fqwer 2019-07-04T02:04:23+08:00 1

df.sort_values() 按照某列排序

参考

pandas常见实用操作

https://zhuanlan.zhihu.com/p/100064394

http://www.360doc.com/content/20/0202/23/7669533_889336554.shtml