Pandas库,如何利用loc或iloc从DataFrame获取或设置数据?
发布于 作者:苏南大叔 来源:程序如此灵动~还是讨论DataFrame
的使用方法,对于类似二维数组的dataframe
,如何访问如何设置其中的数据片段呢?这个就是本文中主要讨论的问题。这个过程中,其实关键因素是如何描述数据的位置。观察dataframe
的索引方式,然后对它进行描述吧。
大家好,这里是苏南大叔的程序如此灵动博客,记录的是苏南大叔和计算机代码的故事。本文描述pandas
中用于定位dataframe
数据的两个函数:loc[]
和iloc[]
。这两个函数有什么区别呢?测试环境:win10
,python@3.6.8
,pandas@1.1.5
。
测试数据
这里先定义两组测试数据:
import pandas as pd
df = pd.DataFrame([
('虎子', 5, "dog"),
('老许', 3, "bird"), ],
)
df2 = pd.DataFrame([
('虎子', 5, "dog"),
('老许', 3, "bird"),
('二赖子', 6, "fish"), ],
columns=("name", "age", "class")
)
df3 = pd.DataFrame([
('虎子', 5, "dog"),
('老许', 3, "bird"),
('二赖子', 6, "fish"), ],
index=["a1", "a2", "a3"],
columns=("name", "age", "class")
)
具体可以参考下面的这个链接:
对于类似二维数据的dataframe
数据结构,可以使用(index,columns)
也就是(行,列)
进行描述。这里最常见的情况,就是行的索引采用“0,1,2”这样的数字索引,而列的索引是自定义的名字。比如上面的数据df2
变量。
- 根据这个
dataframe
数据,对于index
和columns
是否进行了定义,可以选用pandas.DataFrame.loc(index,columns)
和pandas.DataFrame.iloc(index,columns)
这两个函数。 index
和columns
默认是数字,但是如果被定义之后,就必须使用对应的字符串了,数字索引就对于loc[]
不生效,但是对于iloc[]
仍然生效。
loc[index,columns]
index,columns
,可以取值数字,也可以取值字母,这取决于DataFrame
的索引情况。
下面的代码中,返回的是个str
:
# <class 'str'>
print(df.loc[0, 0]) # 虎子
# print(df2.loc[0,1]) # KeyError: 1
# print(df3.loc[0,1]) # KeyError: 1
print(df2.loc[0, "name"]) # 虎子
# print(df3.loc[0,"name"]) # KeyError: 0
print(df3.loc["a1", "name"]) # 虎子
下面的代码中,返回的是Series
:
# <class 'pandas.core.series.Series'>
a2 = df2.loc[:, "name"]
a3 = df2.loc[:2, "name"]
# a4 = df3.loc[1:2, "name"] # TypeError: cannot do slice indexing on Index with these indexers
a4 = df3.loc["a1":"a3", "name"]
a5 = df3.loc["a1":"a3", "name":"class"]
iloc[index,columns]
这个iloc[]
中,必须使用数字索引,这个就是和loc[]
的最主要区别之处。但是,在iloc[]
中,无论dataframe
的索引定义情况如何,都可以使用数字索引。
下面的代码,返回str
类型:
# print(df2.iloc[0,"name"]) # ValueError: Can only index by location with a [integer, integer
print(df.iloc[0, 0]) # 虎子
print(df2.iloc[0, 1]) # 5
print(df3.iloc[0, 1]) # 5
下面的代码,返回Series
类型:
# print(df2.iloc[1,"name"]) #虎子
print(df.iloc[:,1])
print(df2.iloc[2:,1])
print(df3.iloc[:2,1])
print(df3.iloc[:2,0:2])
.values
对于返回值是Series
类型的情况,可以使用.values()
获得ndarray
类型的结果。对于str
类型的情况,会报错。
# print(df.loc[1,2].values) # AttributeError: 'str' object has no attribute 'values'
print(df.loc[:,2].values) # ['dog' 'bird']
# print(df2.loc[0:2,2].values) # KeyError: 2
print(df2.iloc[0:2,2].values) # ['dog' 'bird'] <class 'numpy.ndarray'>
print(df2.iloc[0:2,0:2].values) # [['虎子' 5]['老许' 3]] <class 'numpy.ndarray'>
修改数据
修改一系列数据,这里的index
位置变成了一个条件查询语句。然后增加了一个新的字段ok
。
df2.loc[df2.loc[:, 'name'] == "虎子", "ok"] = 1
测试代码:
import pandas as pd
df = pd.DataFrame(
[
["虎子", "狗", 15],
["老许", "猫", 10],
],
columns=["姓名", "种类", "重量"],
)
# 修改行
df.iloc[1] = ["小许", "猫", 3]
df.iloc[0, :] = ["二赖子", "狗", 16]
print(df)
# 修改列
df.iloc[:, 1] = ["dog", "cat"]
print(df)
输出:
姓名 种类 重量
0 二赖子 狗 16
1 小许 猫 3
姓名 种类 重量
0 二赖子 dog 16
1 小许 cat 3
可能的报错
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
视图直接设置一个值的话,可能会碰到这个警告信息。比如:
df["nan"][4] = None
不报错的版本是:
df.loc[4, "nan"] = None
相关文章
综述
函数 | index | columns |
---|---|---|
loc | 根据情况,可数字,可字母,可范围 | 根据情况,可数字,可字母,可范围 |
iloc | 必须是数字,或数字范围 | 必须是数字,或数字范围 |
函数 | 返回值 |
---|---|
loc(index,column) | 字符串 |
loc(:,:) | Series |
loc(:,:).values | ndarray |
更多pandas
相关文章请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。