簡體   English   中英

pandas過濾連續的行

[英]pandas filtering consecutive rows

我有一個像這樣的Matrix colum的Dataframe

11034-A
11034-B
1120-A
1121-A
112570-A
113-A
113.558
113.787-A
113.787-B
114-A
11691-A
11691-B
117-A RRS
12 X R
12-476-AT-A
12-476-AT-B

我只想過濾只有在連續時以A或B結尾的矩陣,所以在上面的例子中,11034-A和11034-B,113.787-A和113.787-B,11691-A和11691-B,12 -476-AT-A和12-476-AT-B

我編寫了將比較這兩個字符串並返回True或False的函數,問題是我無法看到如何將/ applymap應用於連續的行:

def isAB(stringA, stringB):
    if stringA.endswith('A') and stringB.endswith('B') and stringA[:-1] == stringB[:-1]:
        return True
    else:
        return False

我試過df ['result'] = isAB(df ['Matrix']。str,df ['Matrix'] .shift()。str)無效我似乎缺乏某種方式我設計的方式

編輯:我認為這有效,看起來我在第一次過於復雜:

df['t'] = (df['Matrix'].str.endswith('A') & df['Matrix'].shift(-1).str.endswith('B')) | (df['Matrix'].str.endswith('B') & df['Matrix'].shift(1).str.endswith('A'))
df['p'] = (df['Matrix'].str[:-1] == df['Matrix'].shift(-1).str[:-1]) | (df['Matrix'].str[:-1] == df['Matrix'].shift(1).str[:-1])
df['e'] = df['p'] & df['t']

final = df[df['e']]

我就是這樣做的。

df['ShiftUp'] = df['matrix'].shift(-1)
df['ShiftDown'] = df['matrix'].shift()

def check_matrix(x):
    if pd.isnull(x.ShiftUp) == False and x.matrix[:-1] == x.ShiftUp[:-1]:
        return True
    elif pd.isnull(x.ShiftDown) == False and x.matrix[:-1] == x.ShiftDown[:-1]:
        return True
    else:
        return False

df['new'] = df.apply(check_matrix, axis=1)
df = df.drop(['ShiftUp', 'ShiftDown'], axis=1)
print df

版畫

         matrix    new
0       11034-A   True
1       11034-B   True
2        1120-A  False
3        1121-A  False
4      112570-A  False
5         113-A  False
6       113.558  False
7     113.787-A   True
8     113.787-B   True
9         114-A  False
10      11691-A   True
11      11691-B   True
12    117-A RRS  False
13       12 X R  False
14  12-476-AT-A   True
15  12-476-AT-B   True

這是我的解決方案,需要一些工作。

策略如下:獲取一個新列,該列具有與當前列相同的值但移位了一個位置。

然后,檢查一列是A還是B而另一列是B還是A只是一個問題。

假設您的矩陣列稱為“column_name”。

然后:

myl = ['11034-A',
'11034-B',
'1120-A',
'1121-A',
'112570-A',
'113-A',
'113.558',
'113.787-A',
'113.787-B',
'114-A',
'11691-A',
'11691-B',
'117-A RRS',
'12 X R',
'12-476-AT-A',
'12-476-AT-B']

    #toy data frame
    mydf = pd.DataFrame.from_dict({'column_name':myl})

    #get a new series which is the same one as the original
    #but the first entry contains "nothing"
    new_series = pd.Series(  ['nothing'] + 
    mydf['column_name'][:-1].values.tolist() )

    #add it to the original dataframe
    mydf['new_col'] = new_series

然后定義一個簡單的函數:

def do_i_want_this_row(x,y):

    left_char = x[-1]
    right_char = y[-1]
    return ((left_char == 'A') & (right_char == 'B')) or ((left_char == 'B') & (right_char=='A'))

瞧:

print mydf[mydf.apply(lambda x: do_i_want_this_row( x.column_name, x.new_col), axis=1)]

 column_name      new_col
1       11034-B      11034-A
2        1120-A      11034-B
8     113.787-B    113.787-A
9         114-A    113.787-B
11      11691-B      11691-A
15  12-476-AT-B  12-476-AT-A

還有最后一個元素的問題,但我相信如果您決定遵循這個策略,您可以想一想如何處理它;)

您可以使用DataFrame.drop(labels, axis)從DataFrame中刪除行。 要獲取要刪除的標簽列表,我首先會得到符合您標准的對列表。 使用列表labels上面的labels和您的isAB功能,

pairs = zip(labels[:-1], labels[1:])
delete_pairs = filter(isAB, pairs)

delete_labels = []
for a,b in delete_pairs:
    delete_labels.append(a)
    delete_labels.append(b)

檢查delete_labels以確保您正確地將它們放在一起,

print(delete_labels)

最后,刪除行。 將DataFrame作為x

x.drop(delete_labels) # or x.drop(delete_labels, axis) if appropriate

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM