我正在尝试访问在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
很棒!现在,如果我想将索引合并到函数中怎么办?在添加DataFrame
之前,此d
中任何给定行的索引都是Index([u'a', u'b', u'c', u'd'], dtype='object')
,但是我想要0和1。所以我不能只访问row.index
。
我知道我可以在存储索引的表中创建一个临时列,但是我想知道它是否存储在行对象中的某个位置。
在这种情况下,要访问索引,请访问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
任一:
row.name
调用中包含apply(..., axis=1)
: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
iterrows()
(较慢)DataFrame.iterrows()允许您遍历行并访问它们的索引:
for idx, row in df.iterrows():
...
要回答原始问题:是的,您可以在apply()
中访问行的索引值。它在键name
下可用,并且要求您指定axis=1
(因为lambda处理一行的列而不是列的行)。
工作示例(pandas 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