2016-05-12 37 views
0

我在熊貓中有一對時間序列,並且它會根據行中值的某些條件查看它們的小時間片並提取相同的行。此函數返回兩個數據幀的元組,並刪除這些匹配行並將其放入新數據幀的列表中。處理熊貓中的重複索引DF

我意識到的問題是,它只是可能的(儘管非常不可能)數據幀可能包含兩個相同的索引,在這種情況下,drop命令將刪除原始索引和具有重複索引的行,這偶爾會導致不正確的結果。

請注意,兩個數據幀都會很小,在所有情況下都不到10行,所以可怕的O()行爲很好。

我想到了兩種解決方法,但我不確定如何實現它們。

(1)通過整數位置引用行,但drop看起來不適用於整數規範。我可以這樣做:

df.reset_index().drop(1).set_index(["Thingy", "Other"]) 

重置多指標,而是依靠我知道其他指數級別的名字,感覺真的很慢/哈克。雖然我猜它可能很好。 (2)檢查重複的索引,然後添加一些微小的timedelta給他們,所以他們將不再是重複的,但我無法弄清楚如何優雅地做到這一點。

這裏是這樣的功能的一個簡單的例子:

def extract_pairs(df_first, df_second, threshold=0.0): 
    name1 = df_first.name 
    name2 = df_second.name 
    results = [] 
    flag = False 
    for index1, row1 in df_first.iterrows(): 
     for index2, row2 in df_second.iterrows(): 
      val1 = row1.get_value("SIZE") 
      val2 = row2.get_value("SIZE") 
      if val1*(1-threshold) <= val2 <= val1*(1+threshold) : 
       row1.loc["Name"] = name1 
       row2.loc["Name"] = name2 
       results.append(pd.DataFrame([row1, row2], index=[index1, index2])) 
       flag = True 
       break 
     if flag: 
      break 

    if flag: 
     df_first = df_first.drop(index1) #May remove more than one entry! 
     df_first.name = name1 
     df_second = df_second.drop(index2) #May remove more than one entry! 
     df_second.name = name2 
     df_first, df_second, new_results = extract_pairs(df_first, df_second) 
     results.extend(new_results) 

    return df_first, df_second, results 

==================例========== =====

假設輸入dataframes爲:

Index SIZE   Index SIZE 
A  5    B 5  
A  7    C 6 

當被調用時所期望的輸出是三個幀:

Index SIZE   Index SIZE  Index Name Size  
A  7    C  6   A Foo 5 
             B Bar 5 

但給出的函數的實際輸出爲

Index SIZE   Index SIZE  Index Name Size  
EMPTY DF    C  6   A Foo 5 
             B Bar 5 

因爲降(索引1)線下降所有行索引A.

+0

對不起,你想在這裏實現什麼?你想擺脫其他重複?這是'drop_duplicates'做了什麼,或者你想保留它們併爲重複項添加一些歧義值? – EdChum

+0

我想要df_first.drop(index1)只刪除*由斷開for循環選擇的行。實際上,如果兩個索引相同,則drop也會放棄另一個行。我只想放下我已經識別爲一對的一部分的那一行。 –

+0

@ phil_20686如果'threshold = 1',你想要發生什麼?也就是說,當行X接近(即在行Y和Z的「閾值內」但Y和Z彼此不接近時) – ASGM

回答

1

我想,你可以做以下步驟:

  1. 使用reset_index()把索引數據幀
  2. 您的條件後,選擇行,可使用.index
  3. 使用set_index(index)返回行位置
  4. drop()行,設置「指標」一欄後面爲您指數

我做了下面的例子,我想刪除所有行列A> 0,返回的rowindex將是[1,2,2],但第四行的名稱也是「2」,這是您的問題嗎?

# Generate the dataset 
np.random.seed(1) 
rowname = [1,2,2,2,4,4] 
myDf = pd.DataFrame(np.random.randn(6,4), index=rowname, columns=list('ABCD')) 
print myDf 
>>> 
      A   B   C   D 
1 1.624345 -0.611756 -0.528172 -1.072969 
2 0.865408 -2.301539 1.744812 -0.761207 
2 0.319039 -0.249370 1.462108 -2.060141 
2 -0.322417 -0.384054 1.133769 -1.099891 
4 -0.172428 -0.877858 0.042214 0.582815 
4 -1.100619 1.144724 0.901591 0.502494 

# put your rowindex to your dataframe 
newDf = myDf.reset_index() 

# get the index from the new dataframe, drop them and set the index back to your result 
result = newDf.drop(newDf[newDf.A>0].index).set_index("index") 
print result 

>>>   A   B   C   D 
index           
2  -0.322417 -0.384054 1.133769 -1.099891 
4  -0.172428 -0.877858 0.042214 0.582815 
4  -1.100619 1.144724 0.901591 0.502494