2017-03-13 292 views
0

我有一個由3列組成的熊貓數據框。檢查熊貓數據幀

index start end  value 
    0  0 37647 0 
    1 37648 37846 1 
    2 37847 42874 0 
    3 42875 43049 1 
    4 43050 51352 0 
    5 51353 51665 -1 
    6 51666 54500 0 
    7 54501 54501 -1 
    8 54502 55259 0 

我想實施檢查每行的開始和結束之間的差異。 我特別希望做的是:

if end row x - start row x == 0 incorporate this row in the previous row 

例如排8

7 54501 54501 -1 

已經結束 - 開始= 0我想修改數據框這樣

index start end  value 
    0  0 37647 0 
    1 37648 37846 1 
    2 37847 42874 0 
    3 42875 43049 1 
    4 43050 51352 0 
    5 51353 51665 -1 
    6 51666 54501 0 
    7 54502 55259 0 

然後由於第7行和第8行現在具有相同的「值」,它應該變成

0  0 37647 0 
    1 37648 37846 1 
    2 37847 42874 0 
    3 42875 43049 1 
    4 43050 51352 0 
    5 51353 51665 -1 
    6 51666 55259 0 

EDITED

請注意,一個特定的情況下將是

index start end  value 
    0  0 37647 0 
    1 37648 37846 1 
    2 37847 42874 0 
    3 42875 43049 1 
    4 43050 51352 0 
    5 51353 51665 -1 
    6 51666 54500 0 
    7 54501 54501 -1 
    8 54502 54502 0 
    9 54503 55259 1 

在這種情況下,有2個連續行(第8和9),用於其結束和開始值之間的差爲0 在這種情況下,建議的答案會提供一個錯誤,因爲索引7th先前已被刪除。 我用while循環代替for循環解決了這個問題,但我猜這不是最好的做法。

對於這種情況,我們應該有

index start end  value 
    0  0 37647 0 
    1 37648 37846 1 
    2 37847 42874 0 
    3 42875 43049 1 
    4 43050 51352 0 
    5 51353 51665 -1 
    6 51666 54502 0 
    7 54503 55259 1 

回答

0

使用numpy的where你可以做這樣的:

import numpy as np 

inp = np.where(df.start == df.end)[0] 
droplist = [] 
save = 0 
j = 0 
for i in range(len(inp)): 
    if inp[i] > 0: 
     if inp[i]-inp[i-1] == 1: 
      j += 1 
      save += 1 
      df.loc[inp[i]-1-j,"end"] += save 
     else: 
      j = 0 
      save = 0 
      df.loc[inp[i]-1,"end"] += 1 
     droplist.append(inp[i]) 
df = df.drop(droplist).reset_index(drop=True) 

droplist = [] 
jnp = np.where(df.value == df.value.shift(-1))[0] 
for jj in jnp: 
    df.loc[jj,"end"] = df.loc[jj+1,"end"] 
    droplist.append(jj+1) 
df = df.drop(droplist).reset_index(drop=True) 

有可能是不使用numpy的,雖然for循環更Python的方式。

編輯:固定連續行。

+0

感謝您的解決方案,但如果存在用於該2個連續行(索引)結束和開始值之間的差爲1會有一個錯誤,因爲代碼不會找到以前刪除的索引.. – gabboshow

+0

@ gabboshow - 你能否更新你的問題來反映這種情況,以便我們能夠更好地回答它? – pshep123

+0

嗨克里斯謝謝!會很好,如果ii == 0那麼第一行合併到秒如果第二個如果第二個是OK(即差!= 0),如果第二個也有0作爲開始和結束之間的差異,則第一和第二行應該合併到第三個等等.. – gabboshow

0

這可能會被清理一些,但應該工作。

代碼:

# FIRST CHECK 
df['end'][df['end'].shift(-1) == df['start'].shift(-1)] = df['end'].shift(-1) 
df.drop_duplicates('end', inplace = True) 

# SECOND CHECK 
df['end'][df['value'].shift(-1) == df['value']] = df['end'].shift(-1) 
df['value'][df['value'].shift(-1) == df['value']] = (df['value'] + df['value'].shift(-1)).fillna(0).astype(int) 
df.drop_duplicates('end', inplace = True) 

輸出:

start end value 
0  0 37647  0 
1 37648 37846  1 
2 37847 42874  0 
3 42875 43049  1 
4 43050 51352  0 
5 51353 51665  -1 
6 51666 55259  0 
+0

爲了不獲取SettingWithCopyWarning,您應該在任何位置爲行或數據框的子集分配值時使用'loc' /'iloc'-語法。當你像你一樣從一個布爾過濾器分配一個子集時。 – Khris

+0

謝謝@Khris。更新了答案,不會發出警告和縮減的線條。 – pshep123