パンダの適用関数で行のインデックスを取得する


121

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

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


1
余談ですが、使用する必要がある理由はありますapplyか?フレーム自体でベクトル化された操作を実行するよりもはるかに低速です。(時々、適用何かを行う最も簡単な方法であり、パフォーマンスの考慮はしばしば誇張されますが、特定の例ではそれを使用しないのと同じくらい簡単です。)
DSM

1
@DSM実際には、異なる行要素を使用して各行の別のオブジェクトコンストラクターを呼び出しています。私は質問を説明するために最小限の例を組み合わせたかっただけです。
マイク

回答:


148

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

特定のインデックスレベルをその名前でクエリできるように、のname場合は名前付きタプルであるとよいでしょうMultindex
コンスタンティン

18

どちらか:

1. 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

2.とiterrows()(遅い)

DataFrame.iterrows()を使用すると、行を反復処理して、そのインデックスにアクセスできます。

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

2
そして、関係する、「itertuples」の場合は、一般的にはるかに良い行いますstackoverflow.com/questions/24870953/...
DPB

6

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

動作例(パンダ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

1
MultiIndexを使用したデータフレームでも機能します。row.nameはタプルになります。
チャールズフォックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.