2015-07-03 108 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