2016-05-31 102 views
0

我有基於多個輸入收集的測試數據,並生成單個輸出。我正在將這些數據存儲在一個字典中,其中的鍵是我的參數/結果標籤,其值是測試條件和結果。我希望能夠過濾數據,以便可以基於孤立的條件生成圖。包含列表數據的字典,基於列表中的值的過濾器

在我的例子中,我的測試條件是'a'和'b',實驗的結果是'c'。我想過濾我的數據,所以我得到一個具有相同關鍵字,值結構的字典,只有我的過濾結果。然而,我目前的字典理解返回一個空的字典。任何建議,以獲得理想的結果?

目前代碼:

data = {'a': [0, 1, 2, 0, 1, 2], 'b': [10, 10, 10, 20, 20, 20], 'c': [1.3, 1.9, 2.3, 2.3, 2.9, 3.4]} 
filtered_data = {k:v for k,v in data.iteritems() if v in data['b'] >= 20} 

所需的結果:

{'a': [0, 1, 2], 'b': [20, 20, 20], 'c': [2.3, 2.9, 3.4]} 

當前結果:

{} 

而且,是本詞典列出的一個很好的模式來存儲這類數據,因爲我要過濾結果,還是有更好的方法來實現這一目標?

+1

@SilentMonk,不,它看起來對我來說,他希望繼續在項目'了'和' c''''b''中的對應項目是'= 20' –

+0

你是條件> = 20意味着首先鍵'a'將永遠不會有值和'c',因爲該列表中沒有值那符合你的條件 – reticentroot

+0

@IanMcLaird,明白了。所以我刪除了評論。但是你已經回覆了。抱歉。 – SilentMonk

回答

3

使用本:

k:[v[i] for i,x in enumerate(v) if data['b'][i] >= 20] for k,v in data.items()} 

所需的結果:

{'a': [0, 1, 2], 'c': [2.3, 2.9, 3.4], 'b': [20, 20, 20]} 
+0

謝謝你的回答,但我想要的數據不一定限於'b'中的最後三個值。例如,我可以過濾並獲得'a'= 1的所有值。 –

+0

我更新了代碼:這是否解決了您的問題 –

+0

這樣做,這似乎是不使用熊貓的最佳解決方案。 –

3

考慮在這類工作中使用熊貓模塊。

import pandas as pd 
df = pd.DataFrame(data) 
df = df[df["b"] >= 20] 
print(df) 

看起來像這樣會給你你想要的。您正在使用字典鍵來表示列名稱,並且這些值只是給定列中的行,因此它可以使用數據框。

結果:

a b c 
3 0 20 2.3 
4 1 20 2.9 
5 2 20 3.4 
+1

如果您想重置行索引,請在過濾器下方添加以下內容: 'df.reset_index(drop = True)' –

+0

我以前沒有使用過熊貓,我會研究一下。謝謝。 –

0

是否所有匹配訂單字典值列表?如果是這樣,你可以看看你想要過濾的列表,例如'b',在這種情況下,找到你想要的值,然後在字典中的其他值上使用這些索引或相同的片。

例如:

matching_indices = [] 
for i in data['b']: 
    if data['b'][i] >= 20: 
     matching_indices.append(i) 
new_dict = {} 
for key in data: 
    for item in matching_indices: 
     new_dict[key] = data[key][item] 

你也許可以推測它的字典理解,如果你想要的。希望這很清楚。

+0

是的,我所有的價值觀都是按順序排列的。如果我在使用MATLAB(我的母語)工作,這是我會採用的路線,但是我嘗試使用理解,因爲它們看起來更加高效和pythonic。如果我無法實現這個目標,我將回到迭代循環。謝謝你的幫助。 –

0

你可以改變這種方法,它會給它更多的靈活性。您當前的邏輯意味着,數據集A和C被忽視,因爲沒有值大於或等於20:

data = {'a': [0, 1, 2, 0, 1, 2], 'b': [10, 10, 10, 20, 20, 20], 'c': [1.3, 1.9, 2.3, 2.3, 2.9, 3.4]} 
filter_vals = ['a', 'b'] 
new_d = {} 
for k, v in data.iteritems(): 
    if k in filter_vals: 
    new_d[k] = [i for i in v if i >= 20] 

print new_d 

現在我不是一個大風扇,如果很多if語句,但這樣的事情是直線前進並且可以調用多次

def my_filter(operator, condition, filter_vals, my_dict): 
    new_d = {} 
    for k, v in my_dict.iteritems(): 
    if k in filter_vals: 
     if operator == '>': 
     new_d[k] = [i for i in v if i > condition] 
     elif operator == '<': 
     new_d[k] = [i for i in v if i < condition] 
     elif operator == '<=': 
     new_d[k] = [i for i in v if i <= condition] 
     elif operator == '>=': 
     new_d[k] = [i for i in v if i >= condition] 
    return new_d 
+0

謝謝@reticentroot,來自coralv的回答相同的評論:這是如果我在MATLAB(我的母語)工作,我會採取的路線,但我試圖與理解工作,因爲他們看起來更有效和pythonic。如果我無法實現這個目標,我將回到迭代循環。 –

+0

然後大熊貓可能是你最好的選擇@Michael Lampe – reticentroot

0

我同意上面的熊貓方法。

如果由於某種原因,你討厭大熊貓或是一位老學校的計算機科學家,元組是一種很好的方法來關聯關係數據。在你的例子中,a,b和c列表是列而不是行。對於元組,你會希望保存爲行:

data = {'a':(0,10,1.3),'b':(1,10,1.9),'c':(2,10,2.3),'d':(0,20,2.3),'e':(1,20,2.9),'f':(2,20,3.4)} 

其中,元組存儲在(條件1,條件2,結果)格式,你描述的,你可以調用單個測試或過濾爲您介紹一套。從那裏,你可以得到一個過濾的結果如下:

filtered_data = {k:v for k,v in data.iteritems() if v[1]>=20} 

返回:

{'d': (0, 20, 2.3), 'e': (1, 20, 2.9), 'f': (2, 20, 3.4)} 
+0

感謝您的回答。如果我走這條路線(使用行而不是列),那麼我失去了我的列標題(dict鍵),所以我可以使用列表並按照您的建議過濾。這是一個選項,但我希望保留我的數據傳輸/自我標籤的列標題。 –