0. 前言
- 参考《利用Python进行数据分析》第五章
- 相关源码
- pandas中数据结构组要分为
Series
和DataFrame
。
1. Series
1.1. 基本概念
由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。
1.2. 构造对象Series
1 | # 默认索引为数字,从0开始编号 |
1.3. 其他
- 对值可以直接进行类似Numpy的操作。
- 多个Series之间的操作,会在算术运算中自动对齐不同的索引的数据。
- 索引:修改索引可以直接通过赋值。如
obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
name
属性,与pandas中其他功能有很大联系。
2. DataFrame
2.1. 基本概念
- 包含一组有序的列(Series对象),每列可以是不同的数值类型。
- 既包含行索引又包含列索引。
- 常用属性:
T
axes
:查看行索引与列索引info()
:基本信息
2.2. 构建对象
1 | # 通过字典构建 |
2.3. 行
查看行索引/行名称:
df.index
普通查询(获取单行或多行信息)
- 获取的结果是行对象,而不是Series。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# 切片获取,不能使用单个数字
frame[1:4]
# frame[1] # error
# irow + 行号,只能获取单行
frame.irow(0)
# iloc + 行号,可同时指定列,行列都使用切片编号
# 使用切片时不包含`end`
frame.iloc[1] # 第一行
frame.iloc[:10]
frame.iloc[:, 0] # 第一列
frame.iloc[:10, 5:]
# loc + 索引,可同时指定列,行列都使用索引
# 使用切片时包含`end`
# 类似numpy操作,其中`start:end`是包含`end`的,且取值不一定是整数
frame.loc['row_index']
frame.loc[['row_index1', 'row_index_2']]
frame.loc[:, 'column_index']
frame.loc[:, ['column_index_1', 'column_index_2']]
frame.loc[['row_index1', 'row_index_2'], ['column_index_1', 'column_index_2']]
- 获取的结果是行对象,而不是Series。
查询行数:
len(df.index)
,len(df)
查询前/后几行:
df.head(i), df.tail(i)
行过滤(根据条件删除行)
1
2
3
4
5
6# 单条件过滤,使用df[cond]的形式,cond为bool类型,用于筛选行
df = df[df.age > 10]
df = df[df['age'] > 10]
# 多条件过滤,使用&来连接多个不同条件
df = df[df.age > 10 & df.salary > 1000.]将行随机转换为几个子集(切割dataframe)
1
2
3
4
5
6
7
8
9
10
11# 如果只要随机获取一定比例的样本,可以通过 sample
df.sample(frac=0.5)
# 假设要把df转换为train/val/test,分别是0.8/0.1/0.1的比例,则
num_train = int(len(df)*0.8)
num_val = int(len(df)*0.1)
num_test = len(df) - num_train - num_val
df = df.sample(frac=1.0) # shuffle
train_df = df[:num_train]
val_df = df[num_train:(num_train+num_val)]
test_df = df[:-num_test]增
1
2
3
4
5
6
7
8# 通过loc指定新的行索引,增加行
# 这种方式可以不管类型,直接赋值
df.loc['new_raw_index'] = 1 # 不管数据类型,行所有的数据都为1
df.loc['new_raw_index'] = {'a': 1, 'b': 'two'} # 必须指定所有列,否则报错
# append
# 传入的必须是Series对象、字典、字典列表
df = df.append({'a': 5}, ignore_index=True)遍历行
1
2
3
4
5for row in df.iterrows():
# row 是个元组,包含快两个数据
# row[0] 应该是行索引
# row[1] 是个 Series 对象,可以直接通过 row[1].column_name 来获取数据
pass根据行id删除行:
df.drop([0, 5])
删除重复行:
df.drop_duplicates([0, 5])
,其中选择的是列名,即df.columns
中内容
2.4. 列
查列索引/列名称:
df.columns
查一列或多列
1
2
3
4
5
6
7
8
9
10# 通过字典或属性的方式,获取列对象(Series)
frame2['year']
frame2.year
# 通过icol获取单列(Series)
frame.icol(0)
# 获取多列(DataFrame)
frame[['w']]
frame[['w', 'z']]改
- 可以通过赋值直接修改列的值。要求是标量,或长度与DataFrame匹配。
增
- 对不存在的列赋值,会创建列。
删
- 删除列通过
del
实现,如del frame2['tes']
- 通过
drop
实现,如df.drop([1, 2], axis=1)
,其中选择的是列名,即df.columns
中内容。
- 删除列通过
列数:
df[0].count()
2.5. 其他操作
- 转置,如
frame.T
- 获取行与列:
df.shape
- 替换NAN为0:
df..fillna(0)
- 两个DataFrame拼接成一个:
df.concat([df1, df2])
3. 其他
3.1. 读取文件
- pandas.read_csv 文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# 普通读取
df = pd.read_csv(FILE_PATH)
# 默认情况下,认为文件第一行为Header,即列名
# 如果第一行不是列名,则需要设置 header 为None,如下所示
df = pd.read_csv(FILE_PATH, header=None)
# 默认情况下,文件中没有索引(即行名)
# 如果要设置第一列为行名,可以设置 index_col
df = pd.read_csv(FILE_PATH, index_col=0)
# 如果第一行不是列名,则需要设置 header 为None,如下所示
df = pd.read_csv(FILE_PATH, header=None)
# 分块读取并且遍历,chunksize代表每次读取的行数量
df = pd.read_csv(FILE_PATH, chunksize=1000)
for piece in df:
# piece 可以作为 DateFrame 操作
...
# 读取开头若干行数据,读取前1000行
df = pd.read_csv(FILE_PATH, nrows=1000)
3.2. 写文件
1 | train_df.to_csv('/path/to/target.csv', |