2017-08-08 41 views
0

我有一個數據幀df數以千計的項目,其中列「」的值重複兩到十次。該數據框有七列,其中之一被命名爲「url」;另一個「國旗」。所有這些都是字符串。使用.apply()來比較元素

我想用熊貓來遍歷這些羣體。對於每個組,我希望找到「url」列中的最長項目,並在與該項目對應的「標誌」列中存儲「0」或「1」。我嘗試了以下方法,但無法使其工作。我想1)擺脫下面的循環,和2)能夠通過df.apply(...)

all_groups = df["group"].drop_duplicates.tolist() 

for item in all_groups: 

    df[df["group"]==item].apply(lambda x: Here I would like to compare the items within one group) 

可以申請()和拉姆達比較組中的所有項目中使用這種情況下?任何更快的方式來實現這一點?

謝謝!

+1

用預期的輸出發佈示例DataFrame會很有幫助。 – Alex

+0

'.apply'並不快。它應該被用作*最後的手段*,因爲它僅僅是一個python for-loop的包裝,有點小管家,使它比許多次的直接for循環慢。你爲什麼不提供輸入數據的例子,以及你期望的輸出的例子...... –

+0

你可能會發現'.groupby()。transform()'比'.apply()'更有用。 – AChampion

回答

0

使用groupby().transform(),你可以這樣做:

df['flag'] = df.groupby('group')['url'].transform(lambda x: x.str.len() == x.map(len).max()) 

其中規定df['flag']一個布爾值。如果你需要它作爲0,1然後只需添加.astype(int)到最後。

0

除非您編寫代碼並且發現它運行緩慢,否則不要對其進行優化。用Donald Knuth的話說:「過早優化是萬惡之源。」

如果你想使用applylambda(如問題提到的):

df = pd.DataFrame({'url': ['abc', 'de', 'fghi', 'jkl', 'm'], 'group': list('aaabb'), 'flag': 0}) 

的樣子:

flag group url 
0  0  a abc 
1  0  a de 
2  0  a fghi 
3  0  b jkl 
4  0  b  m 

然後找出哪些元素應該有自己的標誌變量集。

indices = df.groupby('group')['url'].apply(lambda s: s.str.len().idxmax()) 

df.loc[indices, 'flag'] = 1 

注意這隻會得到最大長度的第一個網址。如果您需要不同的行爲,您可以將網址長度與最大值進行比較。

所以df現在看起來像:

flag group url 
0  0  a abc 
1  0  a de 
2  1  a fghi 
3  1  b jkl 
4  0  b  m 
+0

已採取的建議。我之前的代碼執行得很慢,與您的建議(和明確的例子),特別是@AChampion使用.transform,我能夠取消循環和執行花了30秒,而不是20分鐘。這非常有幫助。 –