Pandas使用操作指南

数据帧(DataFrame)是二维数据结构,即数据以行和列的表格方式排列。

数据帧(DataFrame)的功能特点:潜在的列是不同的类型大小可变标记轴(行和列)可以对行和列执行算术运算

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

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

常见使用操作汇总

DataFrame对象

创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 通过列表创建
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

查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 查看行数和列数
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]]) # 同上

修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 列添加
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

1
2
3
4
5
6
7
#②使用函数
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进行

1
2
3
4
5
6
7
8
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()监视运行进度;

1
2
3
4
5
6
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对象的方法,可传入函数、字典等,作用于整个数据框中的每个位置的元素,返回结果的形状与元数据框 一致!

1
2
3
4
5
6
7
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()

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

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

常见数据过滤操作

通过比较值过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 获取某列等于某值的数据集
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对应的方法相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
>>> 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

子字符串过滤,包含某值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 初始化
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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的设置(按行处理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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

参考

pandas常见实用操作

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

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


Pandas使用操作指南
http://example.com/2020/12/22/2020-12-22-Pandas使用操作指南/
作者
NSX
发布于
2020年12月22日
许可协议