web-dev-qa-db-ja.com

pandas apply関数の行のインデックスを取得する

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にアクセスすることはできません。

インデックスを格納するテーブルに一時列を作成できることは知っていますが、行オブジェクトのどこかに格納されているのではないかと思っています。

85
Mike

この場合にインデックスにアクセスするには、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
107
EdChum

apply()はあなたが探しているドロイドではありません。

DataFrame.iterrows() を使用すると、行を反復処理し、名前にアクセスできます。

for name, row in df.iterrows():
    ...
6
smci

元の質問に答えるには、はい、apply()の行のインデックス値にアクセスできます。キーnameの下で使用でき、axis=1を指定する必要があります(ラムダは列の行ではなく行の列を処理するため)。

作業例(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
3