2012-06-23 39 views
9

Tương tự như this R question, tôi muốn áp dụng hàm cho từng mục trong một Series (hoặc mỗi hàng trong một DataFrame) bằng cách sử dụng Pandas, nhưng muốn sử dụng như một đối số cho hàm này chỉ mục hoặc id của hàng đó. Như một ví dụ nhỏ, giả sử người ta muốn tạo một danh sách các bộ dữ liệu của biểu mẫu [(index_i, value_i), ..., (index_n, value_n)]. Sử dụng một Python đơn giản cho vòng lặp, tôi có thể làm: hàng gấu trúc cụ thể áp dụng

In [1] L = [] 
In [2] s = Series(['six', 'seven', 'six', 'seven', 'six'], 
      index=['a', 'b', 'c', 'd', 'e']) 
In [3] for i, item in enumerate(s): 
      L.append((i,item)) 
In [4] L 
Out[4] [(0, 'six'), (1, 'seven'), (2, 'six'), (3, 'seven'), (4, 'six')] 

Nhưng phải có cách hiệu quả hơn để làm điều này? Có lẽ một cái gì đó hơn Panda-ish như Series.apply? Trong thực tế, tôi không lo lắng (trong trường hợp này) về việc trả lại bất cứ điều gì có ý nghĩa, nhưng nhiều hơn cho hiệu quả của một cái gì đó như 'áp dụng'. Bất kỳ ý tưởng?

Trả lời

7

Nếu bạn sử dụng phương pháp áp dụng với chức năng điều xảy ra là mọi mục trong Series sẽ được ánh xạ với chức năng như vậy. Ví dụ.

>>> s.apply(enumerate) 
a <enumerate object at 0x13cf910> 
b <enumerate object at 0x13cf870> 
c <enumerate object at 0x13cf820> 
d <enumerate object at 0x13cf7d0> 
e <enumerate object at 0x13ecdc0> 

Điều bạn muốn làm chỉ đơn giản là liệt kê chính chuỗi đó.

>>> list(enumerate(s)) 
[(0, 'six'), (1, 'seven'), (2, 'six'), (3, 'seven'), (4, 'six')] 

Nếu ví dụ bạn muốn tổng hợp chuỗi của tất cả các thực thể thì sao?

>>> ",".join(s) 
'six,seven,six,seven,six' 

Một cách sử dụng phức tạp hơn của áp dụng sẽ là này một:

>>> from functools import partial 
>>> s.apply(partial(map, lambda x: x*2)) 
a    ['ss', 'ii', 'xx'] 
b ['ss', 'ee', 'vv', 'ee', 'nn'] 
c    ['ss', 'ii', 'xx'] 
d ['ss', 'ee', 'vv', 'ee', 'nn'] 
e    ['ss', 'ii', 'xx'] 

[Chỉnh sửa]

Tiếp theo câu hỏi của OP để làm rõ: Đừng nhầm lẫn Series (1D) với DataFrames (2D) http://pandas.pydata.org/pandas-docs/stable/dsintro.html#dataframe - vì tôi không thực sự thấy cách bạn có thể nói về các hàng. Tuy nhiên bạn có thể bao gồm các chỉ số trong chức năng của bạn bằng cách tạo ra một loạt mới (áp dụng sẽ không cung cấp cho bạn bất kỳ thông tin về chỉ số hiện tại):

>>> Series([s[x]+" my index is: "+x for x in s.keys()], index=s.keys()) 
a  six index a 
b seven index b 
c  six index c 
d seven index d 
e  six index e 

Nhưng dù sao tôi sẽ đề nghị bạn nên chuyển sang kiểu dữ liệu khác để tránh rò rỉ bộ nhớ khổng lồ.

+0

Cảm ơn @ luke14free cho con trỏ về liệt kê. Cuối cùng, tôi có thể cung cấp một ví dụ quá đơn giản, nhưng bạn đã thực sự cung cấp một câu trả lời phù hợp. Những gì tôi thực sự muốn mặc dù, là một cái gì đó giống như ví dụ thứ ba của bạn, với điều kiện bổ sung mà nói, số mũ là một chức năng của hàng hoặc chỉ số ... –

+0

Hey @CarsonFarmer - xem chỉnh sửa cuối cùng của tôi – luke14free

+0

Cảm ơn @ luke14free. Cuối cùng, tôi đã làm như bạn đề nghị, và đi về giải quyết vấn đề của tôi theo một cách khác bằng cách tái cấu trúc dữ liệu của tôi. –

3

Đây là một cách gọn gàng, sử dụng count itertools và zip:

import pandas as pd 
from itertools import count 

s = pd.Series(['six', 'seven', 'six', 'seven', 'six'], 
        index=['a', 'b', 'c', 'd', 'e']) 

In [4]: zip(count(), s) 
Out[4]: [(0, 'six'), (1, 'seven'), (2, 'six'), (3, 'seven'), (4, 'six')] 

Thật không may, chỉ là hiệu quả hơn enumerate(list(s))!

Các vấn đề liên quan