前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >访问和提取DataFrame中的元素

访问和提取DataFrame中的元素

作者头像
生信修炼手册
发布2020-06-24 15:15:26
4.2K0
发布2020-06-24 15:15:26
举报
文章被收录于专栏:生信修炼手册生信修炼手册

访问元素和提取子集是数据框的基本操作,在pandas中,提供了多种方式。对于一个数据框而言,既有从0开始的整数下标索引,也有行列的标签索引

代码语言:javascript
复制
>>> df = pd.DataFrame(np.random.randn(4, 4), index=['r1', 'r2', 'r3', 'r4'], columns=['A', 'B', 'C', 'D'])
>>> df
           A B C D
r1 -0.220018 -0.398571 0.109313 0.186309
r2 -1.416611 0.826713 0.178174 0.117015
r3 -0.640207 -0.105941 -0.139368 -1.159992
r4 -2.254314 -1.228511 -2.080118 -0.212526

利用这两种索引,可以灵活的访问数据框中的元素,具体的操作方式有以下几种

1. 属性运算符

数据框的每一列是一个Series对象,属性操作符的本质是先根据列标签得到对应的Series对象,再根据Series对象的标签来访问其中的元素,用法如下

代码语言:javascript
复制
# 第一步,列标签作为属性,先得到Series对象
>>> s = df.A
>>> s
r1 -0.220018
r2 -1.416611
r3 -0.640207
r4 -2.254314
Name: A, dtype: float64
# 第二步,在根据下标或者标签访问Series对象中的元素
>>> s.r1
-0.22001819046457136
>>> s[0]
-0.22001819046457136

# 属性操作符,一步法简写如下
>>> df.A.r1
-0.22001819046457136

属性操作符,一次只可以返回一个元素,适用于提取单列或者访问具体标量的操作。

2. 索引运算符

这里的索引运算符,有两种操作方式

  1. 对列进行操作,用列标签来访问对应的列
  2. 对行进行切片操作

列标签的用法,支持单个或者多个列标签,用法如下

代码语言:javascript
复制
# 单个列标签
>>> df['A']
r1 -0.220018
r2 -1.416611
r3 -0.640207
r4 -2.254314
Name: A, dtype: float64

# 当然,你可以在列对应的Series对象中再次进行索引操作,访问对应元素
>>> df['A']['r1']
-0.22001819046457136
>>> df['A'][0]
-0.22001819046457136


# 多个列标签
>>> df[['A', 'B']]
           A B
r1 -0.220018 -0.398571
r2 -1.416611 0.826713
r3 -0.640207 -0.105941
r4 -2.254314 -1.228511

对行进行切片的操作,用法如下

代码语言:javascript
复制
>>> df[:2]
           A         B         C         D
r1 -0.220018 -0.398571  0.109313  0.186309
r2 -1.416611  0.826713  0.178174  0.117015

索引操作符,一次只能访问数据框的一个维度,适用于仅操作一个维度的场景。需要注意的是,当对不存在的列标签设值时,并不会报错,会自动进行append操作,示例如下

代码语言:javascript
复制
>>> df['E'] = 5
>>> df
           A B C D E
r1 0.706160 0.097334 0.241069 -0.412934 5
r2 -0.357353 1.053972 0.052277 -1.459352 5
r3 0.341270 0.551733 2.637333 0.494495 5
r4 1.506536 0.635737 1.083644 1.106261 5

另外,索引操作符支持布尔数组,本质是提取True对应的元素,本次示例如下

代码语言:javascript
复制
>>> df = pd.DataFrame(np.random.randn(4, 4), index=['r1', 'r2', 'r3', 'r4'], columns=['A', 'B', 'C', 'D'])
>>> df
           A B C D
r1 0.254875  0.627368 -1.488750 -1.134972
r2 -0.052981 -1.874639 -1.460659  1.020969
r3 -2.046727  1.460599  0.808164 -1.015956
r4 -0.385587  1.534610 -0.043623 -1.742118
>>> (df.A > df.B) & (df.B < df.C)
r1 False
r2 True
r3 False
r4 False
dtype: bool
>>> df[(df.A > df.B) & (df.B < df.C)]
           A B C D
r2 -0.052981 -1.874639 -1.460659  1.020969

3. loc

loc功能灵活且强大,提供了基于标签的访问方式,先操作行标签,再操作列标签,用法如下

代码语言:javascript
复制
# 只提供一个标签,视为行标签
>>> df.loc['r1']
A -0.220018
B -0.398571
C 0.109313
D 0.186309
Name: r1, dtype: float64

# 根据单个行列标签,访问对应元素
>>> df.loc['r1','A']
-0.22001819046457136

# 也支持多个行列标签,用列表的写法
>>> df.loc['r1', ['A', 'B']]
A -0.220018
B -0.398571

# :冒号是所有标签的简写
>>> df.loc[:,'A']
r1 -0.220018
r2 -1.416611
r3 -0.640207
r4 -2.254314

对于标签,支持切片操作,和python内置的切片规则不一样,loc的切片包含了终止点,用法如下

代码语言:javascript
复制
>>> df.loc['r1':'r3', 'A':'C']
           A         B         C
r1 -0.220018 -0.398571  0.109313
r2 -1.416611  0.826713  0.178174
r3 -0.640207 -0.105941 -0.139368

loc也支持布尔数组,本质是提取True对应的标签元素,用法如下

代码语言:javascript
复制
# 布尔数组
# True对应的标签为C和D
>>> df.loc['r1'] > 0
A False
B False
C True
D True
Name: r1, dtype: bool

# 利用布尔数组,提取C,D两列
>>> df.loc[:, df.loc['r1'] > 0]
           C D
r1 0.109313  0.186309
r2 0.178174  0.117015
r3 -0.139368 -1.159992
r4 -2.080118 -0.212526

# 最近构建布尔数组,来提取对应的行
>>> s = pd.Series([False, False, True, True], ['r1', 'r2', 'r3', 'r4'])
>>> s
r1 False
r2 False
r3 True
r4 True
dtype: bool
>>> df.loc[s, :]
           A B C D
r3 -0.640207 -0.105941 -0.139368 -1.159992
r4 -2.254314 -1.228511 -2.080118 -0.212526

loc还支持函数调用,比如一个lambda匿名函数,用法如下

代码语言:javascript
复制
>>> df.loc[:, lambda df: ['A', 'B']]
           A         B
r1 -0.220018 -0.398571
r2 -1.416611  0.826713
r3 -0.640207 -0.105941
r4 -2.254314 -1.228511

函数调用的本质是通过函数返回对应的标签,示例如下

代码语言:javascript
复制
>>> def extract_cols(df):
... return(df.columns[0:2])
...
>>> extract_cols(df)
Index(['A', 'B'], dtype='object')
>>>
>>> df.loc[:, extract_cols]
           A B
r1 -0.220018 -0.398571
r2 -1.416611  0.826713
r3 -0.640207 -0.105941
r4 -2.254314 -1.228511

在函数中,可以根据需要定义复杂的逻辑。需要注意的是,通过loc设置对应的值时,当key不存在时,会默认进行append操作,示例如下

代码语言:javascript
复制
# r5并不存在,但是不会报错
>>> df.loc['r5'] = 1
# 自动追加了r5的内容
>>> df
           A B C D
r1 -0.220018 -0.398571 0.109313 0.186309
r2 -1.416611 0.826713 0.178174 0.117015
r3 -0.640207 -0.105941 -0.139368 -1.159992
r4 -2.254314 -1.228511 -2.080118 -0.212526
r5 1.000000 1.000000 1.000000 1.000000

4. iloc

与loc相对应, iloc提供了基于下标索引访问元素的方式,用法和loc相同,只是将标签替换成了下标索引,示例如下

代码语言:javascript
复制
# 单个索引,视为行索引
>>> df.iloc[0]
A   -0.220018
B   -0.398571
C    0.109313
D    0.186309
Name: r1, dtype: float64
# 单个行列索引
>>> df.iloc[0, 0]
-0.22001819046457136

# 多个行列索引
>>> df.iloc[[0, 1], [0, 1, 2]]
           A         B         C
r1 -0.220018 -0.398571  0.109313
r2 -1.416611  0.826713  0.178174

# 索引切片
>>> df.iloc[:2, :2]
           A         B
r1 -0.220018 -0.398571
r2 -1.416611  0.826713


# 函数调用
>>> df.iloc[:, lambda df: [0, 1]]
           A         B
r1 -0.220018 -0.398571
r2 -1.416611  0.826713
r3 -0.640207 -0.105941
r4 -2.254314 -1.228511

5. at系列函数

上述几种方式都可以访问单个元素,但是由于考虑了很多的功能,其访问速度并不是最快的。针对访问单个元素的常见,pandas推荐使用at和iat函数,其中at使用标签进行访问,iat使用位置索引进行访问,用法如下

代码语言:javascript
复制
>>> df.at['r1', 'A']
-0.22001819046457136
>>> df.iat[0, 0]
-0.22001819046457136

pandas中访问元素的具体方法还有很多,熟练使用行列标签,位置索引,布尔数组这三种基本的访问方式,就已经能够满足日常开发的需求了。

·end·

—如果喜欢,快分享给你的朋友们吧—

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信修炼手册 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档