2017-04-21 100 views
0

經過一段時間的搜索後,我找不到必須是常見問題的答案,因此歡迎使用指針。根據列中列表中的值選擇熊貓數據幀的部分

我有一個數據幀:

df = DataFrame({'A' : [5,6,3,4], 'B' : [1,2,3,5], 'C' : [['a','b'],['b','c'] ,['g','h'],['x','y']]}) 

,我想選擇一個子集,(某些行的),其中有在「C」柱在列表中值,其顯示在列表中我感興趣的東西。例如

listOfInterestingThings = [a, g] 

因此,當過濾器應用於我想有一個DF1:

df1 = 
A B  C  
5 1 ['a','b'] 
3 3 ['g','h'] 

我處理的數據幀是一個巨大的原始數據導入到RAM 12GB〜在當前DF形式。大約是磁盤上的一半,作爲一系列json文件。

+3

標準警告:Series和DataFrames中的非標量元素(例如列表)沒有很好的支持,並可能導致神祕和意外的行爲。警告用具! – DSM

+0

@DSM有趣。不知道。你有什麼建議嗎?我正在做的是在嘗試使用一些ML來訓練主題之前對大型文本語料庫進行基本操作。數據〜6GB的json文件。每個文檔由一個帶有「body」和「topics」標籤的json元素表示,主題以列表形式呈現,例如['topic1','topic2']我用pd.DataFrame.from_dict將數據加載到df。你有沒有更好的方法來處理這種結構的大數據集? –

回答

2

我完全同意@DSM

作爲最後的手段,你可以使用這個:

In [21]: df.loc[pd.DataFrame(df.C.values.tolist(), index=df.index) \ 
        .isin(listOfInterestingThings).any(1)] 
Out[21]: 
    A B  C 
0 5 1 [a, b] 
2 3 3 [g, h] 

或:

In [11]: listOfInterestingThings = set(['a', 'g']) 

In [12]: df.loc[df.C.apply(lambda x: len(set(x) & listOfInterestingThings) > 0)] 
Out[12]: 
    A B  C 
0 5 1 [a, b] 
2 3 3 [g, h] 

說明:

In [22]: pd.DataFrame(df.C.values.tolist(), index=df.index) 
Out[22]: 
    0 1 
0 a b 
1 b c 
2 g h 
3 x y 

In [23]: pd.DataFrame(df.C.values.tolist(), index=df.index).isin(listOfInterestingThings) 
Out[23]: 
     0  1 
0 True False 
1 False False 
2 True False 
3 False False 
1

這也適用於:

df[list(np.any(('a' in i) | ('g' in i) for i in df.C.values))] 

    A B  C 
0 5 1 [a, b] 
2 3 3 [g, h] 

基準:

time df.loc[df.C.apply(lambda x: len(set(x) & listOfInterestingThings)> 0)] 

CPU times: user 873 µs, sys: 193 µs, total: 1.07 ms 
Wall time: 987 µs 

time df[list(np.any(('a' in i) | ('g' in i) for i in df.C.values))] 

CPU times: user 1.02 ms, sys: 224 µs, total: 1.24 ms 
Wall time: 1.08 ms 

time df.loc[pd.DataFrame(df.C.values.tolist(), index=df.index).isin(listOfInterestingThings).any(1)] 

CPU times: user 2.58 ms, sys: 1.01 ms, total: 3.59 ms 
Wall time: 5.41 ms 

因此,簡而言之,@ MaxU的回答是最快的方法。