将数据框映射到字典并从其他单元格查找值?

时间:2021-07-24 11:24:13

标签: python pandas dataframe dictionary

我正在寻找我在我的商店中销售的产品之间的关系。 我有这本字典,里面有购物者碰巧购买的捆绑产品以及产品 ID 和销售额(这些产品是放在一起的)

<头>
价值
('产品1', '产品2') 12
('Product2', 'Product4') 7
('Product3', 'Product1','Product5') 6
('Product5') 4

我还有一个包含产品和产品名称的数据框(我不确定这里是否需要一个数据框,如果需要可以将其转换为字典)

<头>
产品 ID 产品名称
产​​品 1 名称 1
产​​品 2 名称 2
产​​品 3 名称 3
产​​品 4 名称 4

有人可以推荐我使用产品 ID 从数据框中查找产品名称的最佳方法,以便我可以构建这样的东西

<头>
价值
(产品 1,名称 1),(产品 2,名称 2) 12
(产品 2,名称 2),(产品 4,名称 4) 7
(产品 3,名称 3),(产品 1,名称 1),(产品 5,名称 5) 6

我是 Python 新手,我还没有尝试过任何东西。

4 个答案:

答案 0 :(得分:0)

设置:

import pandas as pd
from pprint import pprint

bundles = {
    ("Product 1", "Product 2"): 12,
    ("Product 2", "Product 4"): 7,
    ("Product 3", "Product 1", "Product 5"): 6,
    ("Product 5",): 4,
}

df = pd.DataFrame(
    [{"product": f"Product {n}", "name": f"Name {n}"} for n in range(1, 6)]
)
pprint(bundles)
# {('Product 1', 'Product 2'): 12,
#  ('Product 2', 'Product 4'): 7,
#  ('Product 3', 'Product 1', 'Product 5'): 6,
#  ('Product 5',): 4}
pprint(df)
#      product    name
# 0  Product 1  Name 1
# 1  Product 2  Name 2
# 2  Product 3  Name 3
# 3  Product 4  Name 4
# 4  Product 5  Name 5

可能的解决方案:

# Allow using the "product" values as keys in the .loc below
df = df.set_index("product")

# Use a list comprehension to generate the keys of the new dict
# and another one to generate the dict using the names from df
bundles_by_name = {
    tuple(df.loc[prod, "name"] for prod in prods): bundles[prods] for prods in bundles
}

结果如下:

pprint(bundles_by_name)
# {('Name 1', 'Name 2'): 12,
#  ('Name 2', 'Name 4'): 7,
#  ('Name 3', 'Name 1', 'Name 5'): 6,
#  ('Name 5',): 4}

答案 1 :(得分:0)

这是一个解决方案,它使用 explode() 将元组转换为多行,使用 merge() 将产品 ID 的“映射”连接到名称,并使用 groupby() 将“un-爆炸”结果:

result = (
    df
    .explode('Key')
    .reset_index()
    .merge(id2name, left_on='Key', right_on='Product ID')
    .set_index('index')
    .assign(Product=z[['Key', 'Product Name']].apply(tuple, axis=1))
    .groupby(level=0)
    .agg({'Product': list, 'Value': max})
)

>>> result
                                               Product  Value
row                                                          
0             [(Product1, Name 1), (Product2, Name 2)]     12
1             [(Product2, Name 2), (Product4, Name 4)]      7
2    [(Product1, Name 1), (Product3, Name 3), (Prod...      6
3                                 [(Product5, Name 5)]      4

用于可重现设置的前导是:

df = pd.DataFrame({
    'Key': [
        ('Product1', 'Product2'),
        ('Product2', 'Product4'),
        ('Product3', 'Product1', 'Product5'),
        ('Product5',),        
    ], 'Value': [12, 7, 6, 4]
})

id2name = pd.DataFrame({
    'Product ID': [f'Product{i}' for i in range(6)],
    'Product Name': [f'Name {i}' for i in range(6)],
})

说明

让我们看看上面链接表达式中的各个部分。

首先,将元组分解为多行,每行有一个值:

z = df.explode('Key')
>>> z
        Key  Value
0  Product1     12
0  Product2     12
1  Product2      7
1  Product4      7
2  Product3      6
2  Product1      6
2  Product5      6
3  Product5      4

然后,在 id2name 上合并,但保留原始索引:

z = z.reset_index().merge(id2name, left_on='Key', right_on='Product ID').set_index('index')
>>> z
            Key  Value Product ID Product Name
index                                         
0      Product1     12   Product1       Name 1
2      Product1      6   Product1       Name 1
0      Product2     12   Product2       Name 2
1      Product2      7   Product2       Name 2
1      Product4      7   Product4       Name 4
2      Product3      6   Product3       Name 3
2      Product5      6   Product5       Name 5
3      Product5      4   Product5       Name 5

然后,从列 'Product ID''Product Name' 生成元组:

z = z.assign(Product=z[['Key', 'Product Name']].apply(tuple, axis=1))
>>> z
            Key  Value Product ID Product Name             Product
index                                                             
0      Product1     12   Product1       Name 1  (Product1, Name 1)
2      Product1      6   Product1       Name 1  (Product1, Name 1)
0      Product2     12   Product2       Name 2  (Product2, Name 2)
1      Product2      7   Product2       Name 2  (Product2, Name 2)
1      Product4      7   Product4       Name 4  (Product4, Name 4)
2      Product3      6   Product3       Name 3  (Product3, Name 3)
2      Product5      6   Product5       Name 5  (Product5, Name 5)
3      Product5      4   Product5       Name 5  (Product5, Name 5)

最后,通过对索引 (level=0) 进行分组来再次创建列表(取消分解):

z = z.groupby(level=0).agg({'Product': list, 'Value': max})
>>> z
                                                 Product  Value
index                                                          
0               [(Product1, Name 1), (Product2, Name 2)]     12
1               [(Product2, Name 2), (Product4, Name 4)]      7
2      [(Product1, Name 1), (Product3, Name 3), (Prod...      6
3                                   [(Product5, Name 5)]      4

答案 2 :(得分:0)

非 Pandas 版本(可能不是最有效的)

#input
#If only one product: add a comma after the product, otherwise Python will not recognize it as a tupple
d = {('Product1', 'Product2'):"12", ('Product2', 'Product4'):"7", ('Product3', 'Product1','Product5'):"6", ('Product5',):"4"} 
#Nested list for name references
l = [['Product1', 'Name1'],['Product2', 'Name2'],['Product3', 'Name3'],['Product4', 'Name4'],['Product5', 'Name5']] 
out = {}

for products in d: #Loop through each tuple of products in dictionary d
    t = []
    for product in products: #Loop through each product in the products tupple
        for names in l: #Loop through all names in the names list
            if product == names[0]:
                t.append(names[1]) #Append name to list
    out[tuple(t)] = int(d[products]) #Convert list to tupple and construct the dictionary
        
print(out)

此示例的输出:

{('Name1', 'Name2'): 12, ('Name2', 'Name4'): 7, ('Name3', 'Name1', 'Name5'): 6, ('Name5',): 4}

答案 3 :(得分:0)

我已经创建了自己的数据集并进行了测试,代码如下:

import pandas as pd

df=pd.DataFrame({"Product ID":["123","234","345"],"Product Name":["aa","bb","cc"]})
dff=pd.DataFrame({"Key":[("123","345"),("345","123","234"),("123","234")],"Value":["12","3","4"]})

print(df)
print(dff)

df.set_index("Product ID",inplace=True)
dc=df.to_dict()["Product Name"]

for i,row in enumerate(dff["Key"]):dff["Key"][i]=[(x,dc[x]) for x in row]

print(dff)

输出:

df:
  Product ID Product Name
0        123           aa
1        234           bb
2        345           cc

dff:
               Key   Value
0       (123, 345)    12
1  (345, 123, 234)     3
2       (123, 234)     4

Last dff:
                                 Key   Value
0             [(123, aa), (345, cc)]    12
1  [(345, cc), (123, aa), (234, bb)]     3
2             [(123, aa), (234, bb)]     4

我已经对@Pierre D 可重现的设置数据进行了测试,这是它的代码:

import pandas as pd

df = pd.DataFrame({'Product ID': [f'Product{i}' for i in range(6)],'Product Name': [f'Name {i}' for i in range(6)],})
dff = pd.DataFrame({'Key': [('Product1', 'Product2'),('Product2', 'Product4'),('Product3', 'Product1', 'Product5'),('Product5',)], 'Value': [12, 7, 6, 4]})

print(df)
print(dff)

df.set_index("Product ID",inplace=True)
dc=df.to_dict()["Product Name"]

for i,row in enumerate(dff["Key"]):dff["Key"][i]=[(x,dc[x]) for x in row]

print(dff)

输出:

df:
  Product ID Product Name
0   Product0       Name 0
1   Product1       Name 1
2   Product2       Name 2
3   Product3       Name 3
4   Product4       Name 4
5   Product5       Name 5

dff:
                              Key  Value
0            (Product1, Product2)     12
1            (Product2, Product4)      7
2  (Product3, Product1, Product5)      6
3                     (Product5,)      4

last dff:
                                                 Key  Value
0           [(Product1, Name 1), (Product2, Name 2)]     12
1           [(Product2, Name 2), (Product4, Name 4)]      7
2  [(Product3, Name 3), (Product1, Name 1), (Prod...      6
3                               [(Product5, Name 5)]      4

说明:

df.set_index("Product ID",inplace=True)
dc=df.to_dict()["Product Name"]

我们在这里:

  1. Product Id 设置为索引,
  2. 然后将该数据框更改为字典(dc)。因此,我们可以将 Product Name 替换为 Product Id
for i,row in enumerate(dff["Key"]):dff["Key"][i]=[(x,dc[x]) for x in row]

我们正在做的:

  1. 通过遍历 (Product1, Product2) 列并使用该字典 ([(Product1, Name 1), (Product2, Name 2)]) 创建新的 Key,将 list of tuple 值更改为 dc