2015-07-03 141 views
1

鑑於收入值的表這樣的:如何識別元組的「鍵」/三元組元素的列表?

enter image description here

的一個關鍵點需要注意的(和我的問題的核心)是該品牌名稱將幾乎一如既往,但並非總是如此,包含相應的產品名稱。在最後一次香蕉入境的情況下,它沒有。

我將提取的dict品牌< - >收入雙,拳頭佔那些有多個條目品牌,在這些情況下總結,使用方法描述here。所以:

revenuePerBrandDict = {} 
brandRevenueTuples = [] 
i=0 
for brand in ourTab.columns[1][1:-1]: # ignore first (zeroth) and last row 
    brandRevenueTuples.append((campaign.value, round(ourTab.columns[3][i].value,2))) 
    i+=1 
for key, value in brandRevenueTuples: 
     revenuePerBrandDict[key] = revenuePerBrandDict.get(key, 0) + value 

我會再交叉引用的鍵和值在這個字典每個字典(費用的香蕉快譯通,獼猴桃的字典費用等),並從收入減去支出,每件商品。這些類型的字典將香蕉表,獼猴桃等表中提取看起來像這樣:

enter image description here

如果品牌名稱總是在收益表中包含的產品名稱,然後以彙編適當收集與香蕉開支字典相比較的收入價值,例如,我將提取所有名稱中包含「香蕉」的品牌,並在香蕉費用字典中匹配鍵,對其值進行提取。

但它不,所以我需要另一種方式知道在收入字典中,'OtherBrand'是一個香蕉。香蕉字典,我已經知道它是香蕉,因爲它來自香蕉表)。而不是提取品牌< - >收入對的dict,我可以提取(產品,品牌,收入)的元組的列表或元組,現在我們有產品列提供的附加信息。但是,由於一個元組沒有一個關鍵的概念,我怎麼遍歷整個這個新的集合,以希望的方式(與識別即是OtherBrand是一個香蕉等)提取每個元組的收入

+1

標題沒有按真的不符合這個問題,但我想不出一個簡明扼要地總結問題的更好方法... – Pyderman

+1

*您必須定義哪個字段是邏輯鍵,或提供可爲每個元組構建鍵的映射函數。也就是說,在應用'密鑰函數'後,結果是'(key(t),t)'序列,其中第一項現在保證是密鑰。如果問題是關於*分組的話 - 即。最後是'(k,list_of_t)'的序列或字典,其中k是不同的 - 然後是關於分組,並且與確定關鍵字無關,而關鍵字又是.. *你*必須做的。 – user2864740

+0

@ user2864740是的,你是對的,它更像是一個分組問題,而不是確定/選擇密鑰的問題。 – Pyderman

回答

1

你可以用水果作爲鍵和組品牌:

from collections import defaultdict 
import csv 

with open("in.csv") as f: 
    r = csv.reader(f) 
    next(r) # skip header 
    # fruite will be keys, values will be dicts 
    # with brands as keys and running totals for rev as values 
    d = defaultdict(lambda: defaultdict(int)) 
    for fruit, brand, rev in r: 
     d[fruit][brand] += float(rev) 

其中使用的輸入輸出:

from pprint import pprint as pp 

pp(dict(d)) 
{'Apple': defaultdict(<type 'int'>, {'CrunchApple': 1.7}), 
'Banana': defaultdict(<type 'int'>, {'BananaBrand': 4.0, 'OtherBrand': 3.2}), 
'Kiwi': defaultdict(<type 'int'>, {'NZKiwi': 1.2}), 
'Pear': defaultdict(<type 'int'>, {'PearShaped': 6.2}) 

然後,您可以減去使用按鍵的費用。

使用pandas生活更輕鬆,你可以GROUPBY和金額:

import pandas as pd 

df = pd.read_csv("in.csv") 

print(df.groupby(("A","B")).sum()) 

輸出:

A  B    
Apple CrunchApple 1.7 
Banana BananaBrand 4.0 
     OtherBrand 3.2 
Kiwi NZKiwi  1.2 
Pear PearShaped 6.2 

,或因水果和品牌組:

groups = df.groupby(["A","B"]) 

print(groups.get_group(('Banana', 'OtherBrand'))) 

print(groups.get_group(('Banana', 'BananaBrand'))) 
+0

這是一個xlsx,我需要的數據在第二個選項卡中,所以我使用'openpyxl'。將試圖擺脫你的建議。在這裏不太確定'next()'和'lambda'的意義(儘管這是我第一次遇到next(),並且我今天才開始使用lambda。 – Pyderman

+1

@Pyderman,它只是跳過標題,我們不需要列名,邏輯將完全相同,只需從每一行中提取每一個水果,品牌和rev,使用'lambda:defaultdict(int)'作爲傳遞給defaultdict的對象必須是可調用,因此它允許我們指定我們將使用int/float作爲值 –

+0

感謝Padraic。成功將您的defaultdict方法映射到openpyxl。很好地工作。尚未使用熊貓,我必須檢查它,再次感謝。 – Pyderman

1

在我看來,你想按產品類型從第一個表中分組數據。我建議一個字典,其中關鍵是產品類型,值是元組列表[(brand, revenue),(..., ...)]

然後,對於字典中的每種產品類型,都可以輕鬆地提取該產品的品牌列表,並在需要時製作包含3元組列表的(brand, revenue, expenses)的新字典。

+0

看起來很合理。在我嘗試這樣做之前,我很清楚:你打算* dict中每個項目的每個值都是品牌收入元組列表,是正確的嗎? – Pyderman