lấy chỉ mục của một hàng trong một con gấu trúc áp dụng hàm


121

Tôi đang cố gắng truy cập chỉ mục của một hàng trong một hàm được áp dụng trên toàn bộ DataFrametrong Pandas. Tôi có một cái gì đó như thế này:

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

và tôi sẽ xác định một hàm truy cập các phần tử có một hàng nhất định

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

Tôi có thể áp dụng nó như vậy:

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

Tuyệt vời! Bây giờ nếu tôi muốn kết hợp chỉ mục vào hàm của mình thì sao? Chỉ mục của bất kỳ hàng nhất định nào trong hàng này DataFrametrước khi thêm dsẽ là Index([u'a', u'b', u'c', u'd'], dtype='object'), nhưng tôi muốn 0 và 1. Vì vậy, tôi không thể truy cập row.index.

Tôi biết tôi có thể tạo một cột tạm thời trong bảng nơi tôi lưu chỉ mục, nhưng tôi đang tự hỏi liệu nó có được lưu trữ trong đối tượng hàng ở đâu đó hay không.


1
Ngoài ra: có lý do gì bạn cần sử dụng applykhông? Nó chậm hơn nhiều so với việc thực hiện các hoạt động được vector hóa trên chính khung hình. (Đôi khi áp dụng cách đơn giản nhất để làm điều gì đó, và cân nhắc hiệu suất thường được phóng đại, nhưng ví dụ cụ thể của bạn nó cũng dễ dàng không sử dụng nó.)
DSM

1
@DSM trong thực tế, tôi đang gọi một hàm tạo đối tượng khác cho mỗi hàng bằng cách sử dụng các phần tử hàng khác nhau. Tôi chỉ muốn đưa một ví dụ tối thiểu lại với nhau để minh họa câu hỏi.
Mike

Câu trả lời:


148

Để truy cập chỉ mục trong trường hợp này, bạn truy cập namethuộc tính:

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

Lưu ý rằng nếu đây thực sự là những gì bạn đang cố gắng thực hiện thì những điều sau sẽ hoạt động và nhanh hơn nhiều:

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

BIÊN TẬP

Nhìn lại câu hỏi này hơn 3 năm sau, bạn chỉ có thể làm:

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

nhưng giả sử nó không phải là tầm thường như thế này, bất kể bạn rowFuncđang thực sự làm gì, bạn nên sử dụng các hàm vectorised, và sau đó sử dụng chúng với chỉ mục 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

Sẽ rất tuyệt nếu namesẽ là một bộ được đặt tên trong trường hợp của a Multindex, để một cấp chỉ mục cụ thể có thể được truy vấn bằng tên của nó.
Konstantin

18

Hoặc:

1. với row.namebên trong apply(..., axis=1)cuộc gọi:

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. với iterrows()(chậm hơn)

DataFrame.iterrows () cho phép bạn lặp qua các hàng và truy cập chỉ mục của chúng:

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

2
và, nếu có liên quan, 'itertuples' thường hoạt động tốt hơn nhiều: stackoverflow.com/questions/24870953/…
dpb

6

Để trả lời câu hỏi ban đầu: có, bạn có thể truy cập giá trị chỉ mục của một hàng trong apply(). Nó có sẵn bên dưới khóa namevà yêu cầu bạn chỉ định axis=1(vì lambda xử lý các cột của một hàng chứ không phải các hàng của một cột).

Ví dụ làm việc (gấu trúc 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
Cũng hoạt động cho các khung dữ liệu với MultiIndex: row.name trở thành một bộ.
Charles Fox
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.