2016-09-30 64 views
3

我有以下熊貓數據幀:如何在pandas DataFrame中爲「間隔」匹配多個列?

import pandas as pd 
df = pd.DataFrame('filename.csv') 
print(df) 

order start end value  
1  1342 1357 category1 
1  1459 1489 category7 
1  1572 1601 category23 
1  1587 1599 category2 
1  1591 1639 category1 
.... 
15  792  813 category13 
15  892  913 category5 
.... 

所以,有一個order柱涵蓋各許多行,然後從startend的範圍/間隔爲每一行。然後每行被標記爲某個value(例如category1,category2等)

現在我有另一個數據幀叫做key_df。它基本上是完全一樣的格式:

import pandas as pd 
key_df = pd.DataFrame(...) 
print(key_df) 

order start end value  
1  1284 1299 category4 
1  1297 1309 category9 
1  1312 1369 category3 
1  1345 1392 category29 
1  1371 1383 category31 
.... 
1  1471 1501 category31 
... 

我的目標是拿key_df數據框中,檢查是否間隔匹配start:end在原始數據幀df任何行。如果是這樣,df中的這一行應該標記爲key_df數據幀的value值。

在上面的例子中,數據幀df最終會是這樣的:

order start end value  key_value 
1  1342 1357 category1 category29 
1  1459 1489 category7 category31 
.... 

這是因爲如果你看一下key_df,行

1  1345 1392 category29 

與間隔1::1345-1392在區間落在1::1342-1357在原來的df。同樣,key_df行:

1  1471 1501 category31 

對應於第二行中df

1  1459 1489 category7 category31 

我不能完全肯定

(1)如何實現在大熊貓

這個任務

(2)如何在熊貓中有效地對其進行縮放

可以從if語句開始,例如

if df.order == key_df.order: 
    # now check intervals...somehow 

但這沒有利用數據幀結構。然後必須間隔檢查,即如(df.start =< key_df.start) && (df.end => key_df.end)

我卡住了。在熊貓的「間隔」中匹配多列的最有效方法是什麼? (如果這一條件得到滿足創建一個新列,然後簡單)

回答

1

您可以使用mergeboolean indexing,但如果DataFrames都很大,比例是有問題的:

df1 = pd.merge(df, key_df, on='order', how='outer', suffixes=('','_key')) 
df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] 
print (df1) 
    order start end  value start_key end_key value_key 
3  1 1342 1357 category1  1345.0 1392.0 category29 
4  1 1342 1357 category1  1371.0 1383.0 category31 
5  1 1342 1357 category1  1471.0 1501.0 category31 
11  1 1459 1489 category7  1471.0 1501.0 category31 

編輯的評論:

df1 = pd.merge(df, key_df, on='order', how='outer', suffixes=('','_key')) 
df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] 
df1 = pd.merge(df, df1, on=['order','start','end', 'value'], how='left') 
print (df1) 
    order start end  value start_key end_key value_key 
0  1 1342 1357 category1  1345.0 1392.0 category29 
1  1 1342 1357 category1  1371.0 1383.0 category31 
2  1 1342 1357 category1  1471.0 1501.0 category31 
3  1 1459 1489 category7  1471.0 1501.0 category31 
4  1 1572 1601 category23  NaN  NaN   NaN 
5  1 1587 1599 category2  NaN  NaN   NaN 
6  1 1591 1639 category1  NaN  NaN   NaN 
7  15 792 813 category13  NaN  NaN   NaN 
8  15 892 913 category5  NaN  NaN   NaN 
+0

我注意到這裏有一個錯誤。如果給定行沒有'value_key',則這個值將被丟棄。就我們的目的而言,'df'中的所有行都很好 - 不應該丟棄任何行。如果在給定行中不存在'value_key'(即它不會落在間隔中),那麼應該記錄一個「NaN」。 – ShanZhengYang

+0

那麼你需要添加'合併'與左連接到我的代碼? 'df1 = pd.merge(df,df1,on = ['order','start','end','value'],how ='left')'? – jezrael

+0

感謝您的回答。我應該提到這對於大小爲100 MB(或以上)的數據框不可擴展。我得到一個'MemoryError'。任何想法如何使這個更具擴展性?而不是合併,許多for循環?錯誤: 'File「pandas/src/join.pyx」,第187行,在pandas.algos.full_outer_join''(pandas/algos.c:61680)' 'File「pandas/src/join.pyx」 ,第196行,在' 'pandas.algos._get_result_indexer(pandas/algos.c:61978)' 'MemoryError' – ShanZhengYang

相關問題