การรับดัชนีของแถวในแพนด้าใช้ฟังก์ชัน


121

ฉันกำลังพยายามเข้าถึงดัชนีของแถวในฟังก์ชั่นที่นำไปใช้ทั่วทั้งรายการDataFrameใน Pandas ฉันมีสิ่งนี้:

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 ตามความเป็นจริงฉันกำลังเรียกตัวสร้างวัตถุอื่นสำหรับแต่ละแถวโดยใช้องค์ประกอบแถวที่แตกต่างกัน ฉันแค่อยากจะยกตัวอย่างเล็ก ๆ น้อย ๆ มารวมกันเพื่อแสดงคำถาม
Mike

คำตอบ:


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กำลังทำอะไรอยู่คุณควรใช้ฟังก์ชัน vectorised จากนั้นใช้กับดัชนี 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จะตั้งชื่อทูเปิลในกรณีของ a Multindexเพื่อให้สามารถสอบถามระดับดัชนีเฉพาะได้ด้วยชื่อของมัน
Konstantin

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 กลายเป็นทูเพิล
Charles Fox
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.