pandalar uygulama işlevindeki bir satırın dizinini alma


121

DataFramePandas'ta bir bütün için uygulanan bir işlevdeki bir satırın dizinine erişmeye çalışıyorum . Bende böyle bir şey var:

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

ve belirli bir satırdaki öğelere erişen bir işlev tanımlayacağım

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

Bunu şu şekilde uygulayabilirim:

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

Müthiş! Şimdi dizini işlevime dahil etmek istersem ne olur? Eklemeden DataFrameönce verilen herhangi bir satırın dizini dolacaktır Index([u'a', u'b', u'c', u'd'], dtype='object'), ancak ben 0 ve 1'i istiyorum. Bu yüzden sadece erişemiyorum row.index.

Dizini sakladığım tabloda geçici bir sütun oluşturabileceğimi biliyorum, ancak bunun satır nesnesinde bir yerde depolanıp depolanmadığını merak ediyorum.


1
Bir kenara: kullanmanız gereken bir sebep var applymı? Çerçevenin kendisinde vektörleştirilmiş operasyonlar yapmaktan çok daha yavaştır. (Bazen uygulamak olduğunu şey yapmanın en kolay yolu, ve performans konuları genellikle abartılı, ancak belirli örneğin kolay olarak var değil kullanmak için.)
DSM

1
@DSM Gerçekte her satır için farklı satır öğeleri kullanan başka bir nesne yapıcısı arıyorum. Soruyu açıklamak için minimal bir örneği bir araya getirmek istedim.
Mike

Yanıtlar:


148

Bu durumda dizine erişmek için nameözniteliğe erişirsiniz :

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

Gerçekten yapmaya çalıştığınız şey buysa, aşağıdakilerin işe yaradığını ve çok daha hızlı olduğunu unutmayın:

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

DÜZENLE

Bu soruya 3+ yıl sonra baktığınızda, şunları yapabilirsiniz:

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

ama bunun bu kadar önemsiz olmadığını varsayarsak rowFunc, gerçekte ne yapıyor olursanız olun, vektörleştirilmiş fonksiyonları kullanmaya ve sonra bunları df indeksine karşı kullanmalısınız:

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

A durumunda nameadlandırılmış bir demet olması güzel olurdu Multindex, böylece belirli bir dizin düzeyi adıyla sorgulanabilir.
Konstantin

18

Ya:

1. görüşmenin row.nameiçinde 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. ile iterrows()(daha yavaş)

DataFrame.iterrows () , satırları yinelemenize ve dizinlerine erişmenize olanak tanır:

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

2
ve eğer endişelenirse, 'itertuples' genellikle çok daha iyi performans gösterir: stackoverflow.com/questions/24870953/…
dpb

6

Orijinal soruyu cevaplamak için: evet, içindeki bir satırın dizin değerine erişebilirsiniz apply(). Anahtar altında bulunur nameve belirtmenizi gerektirir axis=1(çünkü lambda bir sütunun satırlarını değil, bir satırın sütunlarını işler).

Çalışma örneği (pandalar 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 içeren veri çerçeveleri için de çalışır: row.name bir demet haline gelir.
Charles Fox
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.