title: Pandas使用操作指南
subtitle: Pandas使用操作指南
date: 2020-12-22
author: NSX
catalog: true
tags:
- Pandas
数据帧介绍:
- 数据帧(DataFrame)是二维数据结构,即数据以行和列的表格方式排列。
- 数据帧(DataFrame)的功能特点:潜在的列是不同的类型大小可变标记轴(行和列)可以对行和列执行算术运算
pandas中的DataFrame可以使用以下构造函数创建:
参数 | 描述 |
---|---|
data | 数据采取各种形式,如:ndarray,series,map,lists,dict,constant和另一个DataFrame |
index | 对于行标签,要用于结果帧的索引是可选缺省值np.arrange(n) |
columns | 列标签 |
dtype | 每列的数据类型。 |
常见使用操作汇总
DataFrame对象
创建
# 通过列表创建
data = [1,2,3,4,5]
df = pd.DataFrame(data)
data = [['Alex',10],['Bob',12],['Clarke',13]]
df = pd.DataFrame(data,columns=['Name','Age'])
# 从ndarrays/Lists的字典来创建
data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
df = pd.DataFrame(data, index=['rank1','rank2','rank3','rank4'])
# 从列表创建数据帧DataFrame
data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
df = pd.DataFrame(data)
# 从系列的字典来创建
d = {'one' : pd.Series([1, 2, 3], index=[0,1,2]),
'two' : pd.Series([1, 2, 3, 4], index=[0,1,2,3])}
df = pd.DataFrame(d)
df
查看
# 查看行数和列数
print(df.shape)
# 查看前n行
print(df.head(5))
# 查看后n行
print(df.tail(5))
# 查看数值型列的汇总统计
print(df.describe())
# 查看列名
df.columns
print(df._stat_axis.values.tolist()) # 行名称
print(df.columns.values.tolist())
# 某一列的列值
df['one']
# 第i行的第j列
print(df.loc[0, "one"]) # 第1行的one列值
print(df.iloc[0, 0]) # 第1行的第一列值,同上
# 多行中的多列
print(df.loc[[2,3],['one','two']]) #选取指定的第2行和第3行,name和age列的数据
print(df.iloc[[2,3], [0,1]]) # 同上
修改
# 列添加
df['three']=pd.Series([10,20,30],index=['a','b','c'])
df['four']=df['one']+df['two']
print (df)
# 列删除
df.pop('two')
print (df)
# 行遍历&切片
print(df[1:3])
for index, row in df.iterrows(): # 第一行的值
print(row)
# 附加行
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=['one', 'two'])
df = df.append(df2)
print (df)
# 删除行
df = df.drop(0)
print (df)
数据处理利器:map
#②使用函数
def gender_map(x):
gender = 1 if x == "男" else 0
return gender
#注意这里传入的是函数名,不带括号
data["gender"] = data["gender"].map(gender_map)
数据处理利器:apply
可以接收各种各样的函数(Python内置的或自定义的),也可以同时处理多列数据;
axis=0代表操作对列columns进行,axis=1代表操作对行row进行
def BMI(series):
weight = series["weight"]
height = series["height"]/100
BMI = weight/height**2
return BMI
# 沿着1轴操作
data["BMI"] = data.apply(BMI,axis=1)
apply()在运算时实际上是一行一行遍历的,IO开销比较大,可以使用progress_apply()监视运行进度;
def xx(a):
return a+1
print(type(data[['height', 'weight']]))
data[['height', 'weight']] = data[['height', 'weight']].progress_apply(xx, axis=1)
data
数据处理利器:applymap
applymap() 是与map() 方法相对应的专属于Dataframe对象的方法,可传入函数、字典等,作用于整个数据框中的每个位置的元素,返回结果的形状与元数据框 一致!
def lowerx(x):
if isinstance(x, str):
return x.lower() + '_'
else:
return x
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() 按照某列排序
参考
https://zhuanlan.zhihu.com/p/100064394
http://www.360doc.com/content/20/0202/23/7669533_889336554.shtml