69_Pandas.DataFrame获取行号和列号
将讲解如何从pandas.DataFrame的行名和列名中获取行号和列号,以及如何从列元素的值中获取行名和行号。
下面对内容进行说明。
- 根据行名和列名获取行号和列号
- get_loc() 方法
- 当行名和列名重复时
- 列表索引、列
- get_loc() 方法
- 从列元素值获取行名称和行号
如果想从行号或列号中获取行、列或元素的值,请参考下面的文章。
以下面的 pandas.DataFrame 为例。
import pandas as pd
df = pd.read_csv('data/sample_pandas_normal.csv', index_col=0)
print(df)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
根据行名和列名获取行号和列号
get_loc() 方法
有一个名为 get_loc() 的方法用于获取 pandas.DataFrame 的索引和列。
如果指定行名或列名作为参数,则将返回行号和列号。行号和列号都是从0开始的整数。 行号是从索引中获取的。
print(df.index.get_loc('Alice'))
# 0
print(df.index.get_loc('Ellen'))
# 4
列号是从列中获得的。
print(df.columns.get_loc('age'))
# 0
print(df.columns.get_loc('point'))
# 2
无论哪种情况,对于不存在的名称都会发生 KeyError 错误。
# print(df.index.get_loc('XXX'))
# KeyError: 'XXX'
# print(df.columns.get_loc('XXX'))
# KeyError: 'XXX'
当行名和列名重复时
如果行名或列名重复,请小心。以下示例使用重复的行名称,但这同样适用于列名称。 使用 rename() 方法更改行名称并准备重复的行名称。
df_dup = df.rename(index={'Charlie': 'Bob'})
print(df_dup)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Bob 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
在这种情况下,get_loc()方法返回一个切片类型对象而不是行号。
print(df_dup.index.get_loc('Bob'))
# slice(1, 3, None)
print(type(df_dup.index.get_loc('Bob')))
# <class 'slice'>
添加更多重复的行名称。
df_dup.rename(index={'Ellen': 'Bob'}, inplace=True)
print(df_dup)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Bob 18 CA 70
# Dave 68 TX 70
# Bob 24 CA 88
# Frank 30 NY 57
如果无法用切片表示,则它将是 bool 类型的 NumPy 数组 numpy.ndarray。
print(df_dup.index.get_loc('Bob'))
# [False True True False True False]
print(type(df_dup.index.get_loc('Bob')))
# <class 'numpy.ndarray'>
slice 对象和 bool 类型数组都可以用于索引引用和 iloc 定位。 bool 类型数组也可以与 loc 一起使用。
print(df_dup[df_dup.index.get_loc('Bob')])
# age state point
# name
# Bob 42 CA 92
# Bob 18 CA 70
# Bob 24 CA 88
print(df_dup.iloc[df_dup.index.get_loc('Bob'), 0])
# name
# Bob 42
# Bob 18
# Bob 24
# Name: age, dtype: int64
注意,对于索引,可以使用query()方法提取元素,而不需要使用get_loc()获取切片对象或bool类型数组。
print(df_dup.query('index == "Bob"'))
# age state point
# name
# Bob 42 CA 92
# Bob 18 CA 70
# Bob 24 CA 88
即使行名和列名重复,如果您想要获取行号和列号而不是切片对象或 bool 类型数组,请按如下所述列出索引和列。
列表索引、列
索引和列可以使用list()转换为标准Python列表(列表类型对象)。
l_index = list(df.index)
print(l_index)
# ['Alice', 'Bob', 'Charlie', 'Dave', 'Ellen', 'Frank']
print(type(l_index))
# <class 'list'>
l_columns = list(df.columns)
print(l_columns)
# ['age', 'state', 'point']
print(type(l_columns))
# <class 'list'>
可以使用列表的 index() 方法获取索引(元素数量)。
print(l_index.index('Bob'))
# 1
如果行名称重复,您可以使用内置函数 enumerate() 和列表理解来获取索引列表。
l_index_dup = list(df_dup.index)
print(l_index_dup)
# ['Alice', 'Bob', 'Bob', 'Dave', 'Bob', 'Frank']
print([i for i, x in enumerate(l_index_dup) if x == 'Bob'])
# [1, 2, 4]
从列元素值获取行名称和行号
我们不会从行名和列名中获取行号和列号,而是向您展示如何从任意列的元素中获取相应的行名和行号。 继续使用下面的 pandas.DataFrame 作为示例。
print(df)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
可以使用 query() 方法根据任何列中元素的条件提取行。返回值是pandas.DataFrame。
print(df.query('state == "CA"'))
# age state point
# name
# Bob 42 CA 92
# Charlie 18 CA 70
# Ellen 24 CA 88
通过列出使用 query() 提取的 pandas.DataFrame 的索引,可以获得特定值的行名称列表。
print(list(df.query('state == "CA"').index))
# ['Bob', 'Charlie', 'Ellen']
如果仅提取一行,则同样适用。如果您想要行名称值而不是列表,只需获取索引的第一个元素 [0] 即可。
print(df.query('state == "TX"'))
# age state point
# name
# Dave 68 TX 70
print(list(df.query('state == "TX"').index))
# ['Dave']
print(df.query('state == "TX"').index[0])
# Dave
如果想获取行号而不是行名,请使用reset_index()将索引重置为从0开始的连续数字,然后执行相同的过程。
print(df.reset_index())
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
print(list(df.reset_index().query('state == "CA"').index))
# [1, 2, 4]
print(list(df.reset_index().query('state == "TX"').index))
# [3]
print(df.reset_index().query('state == "TX"').index[0])
# 3