2014-10-30 66 views
37

我正試圖訪問應用於Pandas中整個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 

真棒!現在如果我想將索引合併到我的函數中呢? 在添加d之前,此DataFrame中的任何給定行的索引將爲Index([u'a', u'b', u'c', u'd'], dtype='object'),但我想要0和1.因此,我不能只訪問row.index

我知道我可以創建在我存儲索引的表的臨時列,但我「米不知道如果在該行對象sotred地方。

+1

旁白:有沒有你需要使用'apply'理由嗎?它比在框架上執行矢量化操作要慢得多。 (有時候*是最簡單的方法來做某事,性能方面的考慮往往被誇大了,但是對於你特定的例子來說,它很容易*而不是使用它。) – DSM 2014-10-30 16:26:25

+1

@DSM實際上我爲每一行調用另一個對象構造函數使用不同的行元素。我只是想舉一個最小的例子來說明這個問題。 – Mike 2014-10-30 17:27:53

+0

'apply()'不是你正在尋找的機器人;改用'df.iterrows()'。看到我的答案。這是一個XY問題 – smci 2018-02-16 04:04:36

回答

45

要訪問該指數在這種情況下,您訪問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 
+0

這裏的任何人的警告。我認爲你從'row.name'得到的索引是該行的數字索引。如果你有一個自定義索引(對每一行說一個字符串UUID),你不能在'apply'中訪問它。更令人困惑的是,對於行'n','df.iloc [n] .name'將在'apply'之外返回行n的UUID,但'apply''row.name'內將返回'n' ...參見:http://stackoverflow.com/questions/18316211/access-index-in-pandas-series-apply – Owen 2017-01-27 11:18:11

+2

@Owen在鏈接的問題,這是一個'系列'不是DF,對於你無法訪問的系列像這樣的索引值,你可以爲一個df。對於需要轉換爲DataFrame的系列,請參閱Jeff的答案,還可以在該系列上執行'to_frame()' – EdChum 2017-01-27 11:21:53

0

apply()不是你正在尋找的機器人。

DataFrame.iterrows()允許您遍歷行和訪問他們的名字:

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