pandas dataframe 用 loc 或 iloc 行列选择

浏览: 5199

参考pandas详细介绍:https://www.jianshu.com/p/79800cad3656


单个索引:选列,得到Series
两个索引:先选列再选行,得到元素本身类型
带冒号的索引:选行,得到DataFrame

df[0] 0列, 得到 Series
df[0][1] 0列1行, 得到 str (所在位置元素本身类型)
df[0][0:2] 0列0~1行, 得到 Series
df[:2] 0~1行所有列, 得到 DataFrame
df[1:3] 1~2行所有列, 得到 DdataFrame
df[0,1] 错 ×

df.loc[0,1] 和 df.iloc[0,1] 的行列索引都在一个中括号内

df.loc[行标签,列标签] 或 df.iloc[行标签,列标签]

第一个参数是行标签,第二个参数是列标签(可选参数,默认为所有列标签)

1. loc 和 iloc 含义

loc,可用column名和index名进行定位

    如:df.loc['A':'B',  '3':'5']
错:df.loc[0:1, 3:5] 因为loc只能是实际的索引名,不能用索引

iloc,意为index locate,是用index索引进行定位,参数是整型

    如:df.iloc[0:2, 3:5]
    错:df.iloc['A']

注意:

 loc是按照标签选择的,所以 loc[:, 'A':'C']会把'A' 'B' 'C' 三列都选出来
而iloc是按照索引选的,所以 iloc[:, 0:2] 只会把索引为0和1列选出来

iloc 只能选取数据表里实际有的行和列,没有则会报错
而 loc 可以选没有的行和列,对其赋值后就可以添加新行或新列
df.shape # (7,100)
df.loc[8]=df.iloc[7] # 把索引7行赋值给标签8这行,名字为8,这里8是数字型
df.loc['8']=df.iloc[7] # 把索引7行赋值给标签'8'行,名字为'8',这里'8'是字符串 

 2. 返回类型

两个参数既可以是列表[]也可以是单个字符

否则若列是单个字符(单列)或单行,而无论行是列表还是单个字符,返回皆为Series。
type(df.iloc[[1,6],3]) # Series 多行单列
type(df.iloc[:,3]) # Series 单列
type(df.iloc[2,:]) # Series 单行
type(df.iloc[1,3]) # float64 单元素

Series可以相加
foo.iloc[:,0]+foo.iloc[:,1]+foo.iloc[:,2] 是分别取三列的值相加了

如果列为单列,但是是列表或多列或多行则返回的是DataFrame
type(df.iloc[[1,6],[1]]) # DataFrame 单列的列表
type(df.iloc[1:6,[1]]) # DataFrame 单列的列表
type(df.iloc[:,0:2]) # DataFrame 多列
type(df.iloc[2:4,:]) # Dataframe 多行

Dataframe的加法是,相同的列会相加,缺失的列会是NaN
foo.iloc[:,[3]]+foo.iloc[:,[2]],加出来全是NaN
foo.iloc[:,0:3]+foo.iloc[:,0:2], 前两列相加,第三列全是NaN

3. iloc选取

# 单行
df.iloc[0]  # 第一行
df.iloc[-1] # 最后一行
    
# 单列
df.iloc[:, 0]  # 第一列
df.iloc[:, -1] #最后一列 

# 连续多行
df.iloc[0:5]

# 连续多列
df.iloc[:, 0:2]

# 连续多行、 连续多列
df.iloc[0:5, 5:8]

# 指定行、 连续多列
df.iloc[[0,2], 5:8]

# 指定行、指定列
df.iloc[[0, 3], [0, 5]]

4. 常用函数

# 获取行数
df.shape[0]
# 获取列数
df.shape[1]
# 显示头部数据
df.head
df.head()
# 显示尾部数据
df.tail
df.tail()
# 筛选并修改某个值:选取city列中不为空的位置替换为“Beijing”,df是一个二维数据集,注意不空的行外面用括号
df.loc[(df.city.notnull()), 'city' ] = "Beijing"
df['city'] 或 df.city 直接选这列
df.city.notnull() 选city不空的行

5. 行列取名、修改

# 获取行名
df._stat_axis.values.tolist()
# 获取列名
df.columns.values.tolist()
# 或
list(df)

# 根据行索引取行名
str(df._stat_axis[0])

# 改所有列名
df.columns=['a','b','c']
# 改某列名
df.rename(columns={'a':'aa'},inplace=True)

# 向右合并两列
df = pd.concat([df1,df2], axis=1)
# 向下合并两列(要赋值,否则df1不变)
df1 = df1.append(df2)

df = pd.read_excel('foo.xlsx')
# 修改成日期型
df['Date'] = pd.to_datetime(df['Date'])
# 排序
df = df.sort_values('Date')

df.columns = ['Date','Amount']
df.set_index('Date', inplace=True)

6.  赋值、浅拷贝、深拷贝

Python中对象赋值是浅拷贝,实际上是简单的对象引用。Python并未拷贝对象,只是拷贝了对象的引用。相当于只传递地址,虽然两个变量名不同,但实际的地址却是一样的。改变一个的值会影响另一个。
而深拷贝,修改值不影响原dataframe,将使用调用对象的数据和索引的副本创建新对象。对副本的数据或索引的修改不会反映在原始对象中。
import copy
a = [1,3,2]
b = copy.copy(a) # 浅拷贝,修改b影响a
b = copy.deepcopy(a) # 深拷贝,修改b不影响a
b = a # 浅拷贝,修改b影响a
pandas dataframe:
df1 = df.copy(deep=True) # 深拷贝
df1 = df.copy() # 深拷贝,默认deep=True
df1 = df.copy(deep=False) # 浅拷贝,仅复制对数据和索引的引用。对浅层副本任何修改都影响原始数据,反之亦然。

7. timestamp

import pandas as pd
from datetime import datetime as dt
p1=pd.Timestamp(2017,6,19)
p2=pd.Timestamp(dt(2017,6,19,hour=9,minute=13,second=45))
p3=pd.Timestamp("2017-6-19 9:13:45")
p4=pd.to_datetime("2017-6-19 9:13:45")
p5=pd.to_datetime(dt(2017,6,19,hour=9,minute=13,second=45))




参考:

https://blog.csdn.net/chixujohnny/article/details/50340213

https://blog.csdn.net/csdn15698845876/article/details/73456967

https://blog.csdn.net/u011630575/article/details/78604226?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

推荐 0
本文由 safa 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册