簡體   English   中英

在pandas DataFrame中有效地查找匹配的行(基於內容)

[英]Efficiently find matching rows (based on content) in a pandas DataFrame

我正在編寫一些測試,我正在使用Pandas DataFrames來存放大型數據集〜(600,000 x 10)。 我從源數據中提取了10個隨機行(使用Stata),現在我想編寫一個測試,看看這些行是否在我的測試套件的DataFrame中。

作為一個小例子

np.random.seed(2)
raw_data = pd.DataFrame(np.random.rand(5,3), columns=['one', 'two', 'three'])
random_sample = raw_data.ix[1]

這里raw_data是:

在此輸入圖像描述

派生random_sample以保證匹配,並且:

在此輸入圖像描述

目前我寫了:

for idx, row in raw_data.iterrows():
    if random_sample.equals(row):
        print "match"
        break

哪個有效,但在大數據集上非常慢。 有沒有更有效的方法來檢查DataFrame中是否包含整行?

BTW:我的例子還需要能夠比較np.NaN相等,這就是我使用equals()方法的原因

equals似乎沒有廣播,但我們總是可以手動進行相等比較:

>>> df = pd.DataFrame(np.random.rand(600000, 10))
>>> sample = df.iloc[-1]
>>> %timeit df[((df == sample) | (df.isnull() & sample.isnull())).all(1)]
1 loops, best of 3: 231 ms per loop
>>> df[((df == sample) | (df.isnull() & sample.isnull())).all(1)]
              0         1         2         3         4         5         6  \
599999  0.07832  0.064828  0.502513  0.851816  0.976464  0.761231  0.275242   

               7        8         9  
599999  0.426393  0.91632  0.569807  

這比我的迭代版本要快得多(大概需要30秒)。

但是由於我們有很多行和相對較少的列,我們可以循環遍歷列,並且在典型情況下可能會大幅減少要查看的行數。 例如,像

def finder(df, row):
    for col in df:
        df = df.loc[(df[col] == row[col]) | (df[col].isnull() & pd.isnull(row[col]))]
    return df

給我

>>> %timeit finder(df, sample)
10 loops, best of 3: 35.2 ms per loop

這大約快一個數量級,因為在第一列之后只剩下一行。

(我想我曾經有過一種更為流暢的方式來做這件事,但對於我的生活,我現在不記得了。)

我提出的最好的方法是采用過濾方法,該方法似乎運行良好,並在數據集很大時阻止了大量的比較:

tmp = raw_data    
for idx, val in random_sample.iteritems():
    try:
        if np.isnan(val):
            continue
    except:
        pass
    tmp = tmp[tmp[idx] == val]
if len(tmp) == 1: print "match"

注意:對於上面的小維度示例,這實際上是較慢的。 但是在大型數據集上,這比基本迭代快~9倍

暫無
暫無

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

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