2016-06-12 17 views
1

我想做到以下幾點:刪除重複的行,但保持與特定值的那些在一列(熊貓蟒蛇)

;如果兩行有完全的3列(「ID」相同的價值」符號「和」日期「),並在一列(」消息「)中具有」X「或」T「,然後刪除這兩行。但是,如果兩行在相同的3列中具有相同的值,但在另一列中的值不同於「X」或「T」,則保持不變。

這是我的數據幀的一個示例:

df = pd.DataFrame({"ID":["AA-1", "AA-1", "C-0" ,"BB-2", "BB-2"], "symbol":["A","A","C","B","B"], "date":["06/24/2014","06/24/2014","06/20/2013","06/25/2014","06/25/2015"], "message": ["T","X","T","",""] }) 

注意,前兩行具有用於列「ID」,「符號」,和「日期」的值相同的值,和「T 「和」X「在」消息「欄中。我想刪除這兩行。

但是,最後兩行在列「ID」,「符號」和「日期」中具有相同的值,但在「消息」列中爲空白(不同於「X」或「T」)。

我有興趣將函數應用到有數百萬行的大型數據集。到目前爲止,我曾嘗試佔用我所有的記憶,

謝謝你,我感謝所有幫助,

+0

只是爲了澄清 - 你是否想保留重複行以防萬一有2個以上? – Stefan

+0

我應該在我的問題中更清楚地說明。我的數據是成對的。對於每個「X」行,除了「消息」列之外,(或至少應該是)恰好一個「T」行與其他列相等。在這種情況下,至少在數據收集正確的情況下,應該只有一對匹配的觀測值。 – dleal

回答

0

這可能會爲你工作:

vals = ['X', 'T'] 
pd.concat([df[~df.message.isin(vals)], df[df.message.isin(vals)].loc[~df.duplicated(subset=['ID', 'date', 'symbol'], keep=False), :]]) 

    ID  date message symbol 
3 BB-2 06/25/2014    B 
4 BB-2 06/25/2015    B 
2 C-0 06/20/2013  T  C 

這是相當快的:

%%timeit 
pd.concat([df[~df.message.isin(['X', 'T'])], df[df.message.isin(['X', 'T'])].loc[~df.duplicated(subset=['ID', 'date', 'symbol'], keep=False), :]]) 
100 loops, best of 3: 1.99 ms per loop 

%%timeit 
df.groupby(['ID','date','symbol']).filter(lambda x: ~x.message.isin(['T','X']).all()) 
100 loops, best of 3: 2.71 ms per loop 

另一種選擇是給索引錯誤。

+0

有問題'如果兩行在...'完全相同的價值 - 你的解決方案過濾所有重複行,不僅與長度爲2 – jezrael

+0

這是正確的,我只是下面的標題指令。讓我們看看需要什麼。如果OP想要保留重複的行(如果有多於2個),我的回答將無濟於事。 – Stefan

+0

concat函數運行速度明顯快於groupby,在這種情況下 – dleal

0

我認爲你可以使用groupbyfilter - 條件是 - 不是2行有重複值,並在組列messageisin沒有重視TX

import pandas as pd 

df = pd.DataFrame({"ID":["AA-1", "AA-1", "C-0" ,"BB-2", "BB-2"], 
        "symbol":["A","A","C","B","B"], 
        "date":["06/24/2014","06/24/2014","06/20/2013","06/25/2015","06/25/2015"], 
        "message": ["T","X","T","",""] }) 
print (df) 
    ID  date message symbol 
0 AA-1 06/24/2014  T  A 
1 AA-1 06/24/2014  X  A 
2 C-0 06/20/2013  T  C 
3 BB-2 06/25/2015    B 
4 BB-2 06/25/2015    B 

df1 = df.groupby(['ID','date','symbol']).filter(lambda x: ~((len(x) == 2) & 
                  (x.message.isin(['T','X']).all()))) 
print (df1) 
    ID  date message symbol 
2 C-0 06/20/2013  T  C 
3 BB-2 06/25/2015    B 
4 BB-2 06/25/2015    B 

Filtration in docs

EDIT通過comment

import pandas as pd 

df = pd.DataFrame({"ID":["AA-1", "AA-1", "C-0", "C-0","BB-2", "BB-2"], 
        "symbol":["A","A","C","C", "B","B"], 
        "date":["06/24/2014","06/24/2014","06/20/2013","06/20/2013","06/25/2015","06/25/2015"], 
        "message": ["T","X","X","X","",""] }) 
print (df) 
    ID  date message symbol 
0 AA-1 06/24/2014  T  A 
1 AA-1 06/24/2014  X  A 
2 C-0 06/20/2013  X  C 
3 C-0 06/20/2013  X  C 
4 BB-2 06/25/2015    B 
5 BB-2 06/25/2015    B 

如果需要,每組XT刪除值 - 這意味着它除去雙X或雙T太和每個組的每個len總是2

df1 = df.groupby(['ID','date','symbol']).filter(lambda x: ~x.message.isin(['T','X']).all()) 
print (df1) 
    ID  date message symbol 
4 BB-2 06/25/2015    B 
5 BB-2 06/25/2015    B 

如果需要刪除只有值爲TX的組,可以首先通過檢查每個組中的第一個值是T和第二個X,通過message然後filter。 ( 'T' 是第一和X是第二,因爲排序):

df2 = df.sort_values('message') 
     .groupby(['ID','date','symbol'], sort=False) 
     .filter(lambda x: ((x.message.iloc[0] != 'T') | (x.message.iloc[1] != 'X'))) 
print (df2) 
    ID  date message symbol 
4 BB-2 06/25/2015    B 
5 BB-2 06/25/2015    B 
2 C-0 06/20/2013  X  C 
3 C-0 06/20/2013  X  C 
相關問題