在熊猫应用函数中获取行的索引

Posted

技术标签:

【中文标题】在熊猫应用函数中获取行的索引【英文标题】:getting the index of a row in a pandas apply function 【发布时间】:2014-12-26 19:17:12 【问题描述】:

我正在尝试访问在 Pandas 中应用于整个 DataFrame 的函数中的行索引。我有这样的事情:

df = pandas.DataFrame([[1,2,3],[4,5,6]], columns=['a','b','c'])
>>> df
   a  b  c
0  1  2  3
1  4  5  6

我将定义一个函数来访问具有给定行的元素

def rowFunc(row):
    return row['a'] + row['b'] * row['c']

我可以这样应用它:

df['d'] = df.apply(rowFunc, axis=1)
>>> df
   a  b  c   d
0  1  2  3   7
1  4  5  6  34

太棒了!现在,如果我想将索引合并到我的函数中怎么办? 在添加d 之前,此DataFrame 中任何给定行的索引将为Index([u'a', u'b', u'c', u'd'], dtype='object'),但我想要0 和1。所以我不能只访问row.index

我知道我可以在存储索引的表中创建一个临时列,但我想知道它是否存储在某处的行对象中。

【问题讨论】:

旁白:您是否有理由需要使用apply?它比在帧本身上执行矢量化操作要慢得多。 (有时 apply 做某事的最简单方法,性能考虑经常被夸大,但对于您的特定示例,使用它就像 not 一样容易。) @DSM 实际上,我使用不同的行元素为每一行调用另一个对象构造函数。我只是想把一个最小的例子放在一起来说明这个问题。 【参考方案1】:

要么:

1。在apply(..., axis=1) 调用中使用row.name

df = pandas.DataFrame([[1,2,3],[4,5,6]], columns=['a','b','c'], index=['x','y'])

   a  b  c
x  1  2  3
y  4  5  6

df.apply(lambda row: row.name, axis=1)

x    x
y    y

2。与iterrows()(较慢)

DataFrame.iterrows() 允许您遍历行并访问它们的索引:

for idx, row in df.iterrows():
    ...

【讨论】:

如果担心的话,'itertuples' 通常表现要好得多:***.com/questions/24870953/…【参考方案2】:

回答原始问题:是的,您可以访问apply() 中一行的索引值。它在键 name 下可用,并要求您指定 axis=1(因为 lambda 处理行的列而不是列的行)。

工作示例(熊猫 0.23.4):

>>> import pandas as pd
>>> df = pd.DataFrame([[1,2,3],[4,5,6]], columns=['a','b','c'])
>>> df.set_index('a', inplace=True)
>>> df
   b  c
a      
1  2  3
4  5  6
>>> df['index_x10'] = df.apply(lambda row: 10*row.name, axis=1)
>>> df
   b  c  index_x10
a                 
1  2  3         10
4  5  6         40

【讨论】:

也适用于具有 MultiIndex 的数据帧:row.name 变为元组。【参考方案3】:

在这种情况下,要访问索引,您需要访问 name 属性:

In [182]:

df = pd.DataFrame([[1,2,3],[4,5,6]], columns=['a','b','c'])
def rowFunc(row):
    return row['a'] + row['b'] * row['c']

def rowIndex(row):
    return row.name
df['d'] = df.apply(rowFunc, axis=1)
df['rowIndex'] = df.apply(rowIndex, axis=1)
df
Out[182]:
   a  b  c   d  rowIndex
0  1  2  3   7         0
1  4  5  6  34         1

请注意,如果这确实是您正在尝试做的事情,那么以下工作会更快:

In [198]:

df['d'] = df['a'] + df['b'] * df['c']
df
Out[198]:
   a  b  c   d
0  1  2  3   7
1  4  5  6  34

In [199]:

%timeit df['a'] + df['b'] * df['c']
%timeit df.apply(rowIndex, axis=1)
10000 loops, best of 3: 163 µs per loop
1000 loops, best of 3: 286 µs per loop

编辑

3 年后再看这个问题,你可以这样做:

In[15]:
df['d'],df['rowIndex'] = df['a'] + df['b'] * df['c'], df.index
df

Out[15]: 
   a  b  c   d  rowIndex
0  1  2  3   7         0
1  4  5  6  34         1

但假设它不像这样微不足道,无论您的 rowFunc 真正在做什么,您都应该考虑使用矢量化函数,然后将它们用于 df 索引:

In[16]:
df['newCol'] = df['a'] + df['b'] + df['c'] + df.index
df

Out[16]: 
   a  b  c   d  rowIndex  newCol
0  1  2  3   7         0       6
1  4  5  6  34         1      16

【讨论】:

如果nameMultindex 的情况下是一个命名元组会很好,这样就可以通过其名称查询特定的索引级别。

以上是关于在熊猫应用函数中获取行的索引的主要内容,如果未能解决你的问题,请参考以下文章

从过滤的熊猫数据框中获取整数索引值

在熊猫中获取与给定日期时间最接近的时间戳的行的有效方法

如何从熊猫系列中获取包含行索引的列表[重复]

如何从 SQL Server 中的表中获取行的索引?

如何获取熊猫数据框中的行,列中具有最大值并保留原始索引?

获取回答熊猫过滤器的所有值的索引