2015-09-15 77 views
2

比方說,這是我的函數:熊貓:如何將功能應用到不同的列

def function(x): 
    return x.str.lower() 

這是我的數據框(DF)

A   B  C  D 
0 1.67430 BAR 0.34380 FOO 
1 2.16323 FOO -2.04643 BAR 
2 0.19911 BAR -0.45805 FOO 
3 0.91864 BAR -0.00718 BAR 
4 1.33683 FOO 0.53429 FOO 
5 0.97684 BAR -0.77363 BAR 

我想申請該功能僅限於列BD。 (將其應用於完整的DataFrame不是答案,因爲它會在數字列中生成NaN值)。

這是我的基本思想是:df.apply(function, axis=1)

但我無法捉摸如何選擇不同的列到功能應用到。我試過所有的方式索引的數字位置,名稱等

我花了相當多的時間閱讀這個。這不是任何這些直接重複:

How to apply a function to two columns of Pandas dataframe

Pandas: How to use apply function to multiple columns

Pandas: apply different functions to different columns

Python Pandas: Using 'apply' to apply 1 function to multiple columns

回答

4

單從DF子查詢的列,通過忽略axis PARAM我們以列方式而不是按行方式進行操作,這將會顯着,因爲您的行數多於列:

df[['B','D']].apply(function) 

這將運行FUNC對每列

In [186]: 
df[['B','D']].apply(function) 

Out[186]: 
    B D 
0 bar foo 
1 foo bar 
2 bar foo 
3 bar bar 
4 foo foo 
5 bar bar 

您還可以過濾使用df剛剛得到的字符串D型列:

In [189]: 
df.select_dtypes(include=['object']).apply(function) 

Out[189]: 
    B D 
0 bar foo 
1 foo bar 
2 bar foo 
3 bar bar 
4 foo foo 
5 bar bar 

時序

列式與行式:

In [194]:  
%timeit df.select_dtypes(include=['object']).apply(function, axis=1) 
%timeit df.select_dtypes(include=['object']).apply(function) 

100 loops, best of 3: 3.42 ms per loop 
100 loops, best of 3: 2.37 ms per loop 

然而,對於顯著較大的DFS(逐行)的第一種方法將規模好得多

+0

這是偉大的。理想情況下,我想要這樣做'就地'可以說,而不是子集。現在使用你的答案很簡單:'df [['B','D']] = df [['B','D']]。apply(function)' – RDJ

+1

好聽,如果我的答案解決了問題請接受 – EdChum

3

應用不是就地,它返回一個新的數據幀,所以問題是你能在返回完整數據幀一個去。
你可以做到這一點,但它是醜陋的(這可能是稍快):

df.apply(lambda x: x.str.lower() if x.name in ['B', 'D'] else x) 

如果你想它做的所有字符串列,你可以只檢查D型。

+0

好信息。在我的實際數據中,我將7種不同的'str'方法應用於列,所以函數是最好的。未來會記住這一點。 – RDJ

+1

你可以用'function(x)'替換'x.str.lower()'。 – AChampion

2

清潔語法就地編輯原始列:

df[["A", "B"]] = df[["A","B"]].apply(lambda x: x.str.lower()) 

此外,對新列添加到原始數據幀:

df[["new_col1", "new_col2"]] = df[["A","B"]].apply(lambda x: x.str.lower()) 
2

逐列應用功能IN-地點編輯:

In [194]: df = pd.DataFrame({"A": ["FOO","BAAR","FOO"], "B": ["FOO","BAR" , "FOO"]}) 

In [195]: df.loc[:,["A","B"]].apply(lambda col : col.str.lower(), axis = 0) # axis= 0, Default in pandas 
Out[195]: 
     A B 
0 foo foo 
1 baar bar 
2 foo foo 

逐行應用功能就地編輯,如果需要的話:使用逐列和行嚮應用功能

In [201]: df.loc[:,["A","B"]].apply(lambda row : row.str.lower(), axis = 1) 
Out[201]: 
     A B 
0 foo foo 
1 baar bar 
2 foo foo 

其他有用的操作:

# For column-wise operation using apply function: 
In [224]: df = pd.DataFrame({"A": ["FOO","BAAR","FOO"], "B": ["FOO","BAR" , "FOO"]}) 

In [225]: df.loc[:,["A","B"]].apply(lambda col : col.str.lower() + "_" + "cool" + "_" + df["B"]) 
Out[225]: 
       A    B 
0 foo_cool_FOO foo_cool_FOO 
1 baar_cool_BAR bar_cool_BAR 
2 foo_cool_FOO foo_cool_FOO 

#Note only second element from each column is taken as an argument for lambda function, so NaN for others: 
In [226]: df.loc[:,["A","B"]].apply(lambda col : col[1:2].str.lower() + "_"+ "cool" + "_" + df["B"]) 
Out[226]: 
       A    B 
0   NaN   NaN 
1 baar_cool_BAR bar_cool_BAR 
2   NaN   NaN 


#For Row-wise operation (row[0] & row[1] points to first and second element of each row, 
#or can be called as row["A"] $ row["B"] respectively): 
In [207]: df.loc[:,["A","B"]].apply(lambda row : row["B"].lower() + "_" + row["A"].lower() , axis = 1) 
Out[207]: 
0  foo_foo 
1 bar_baar 
2  foo_foo 
dtype: object 

In [208]: df.loc[:,["A","B"]].apply(lambda row : row[1].lower() + "_" + row[0].lower() , axis = 1) 
Out[208]: 
0  foo_foo 
1 bar_baar 
2  foo_foo 
dtype: object 

#Here, row[1] indicates second element of each row, i.e row["B"] : 
In [235]: df.loc[:,["A","B"]].apply(lambda row : row.str.lower() + "_"+ row[1], axis = 1) 
Out[235]: 
      A  B 
0 foo_FOO foo_FOO 
1 baar_BAR bar_BAR 
2 foo_FOO foo_FOO