我有如下所示的Python dict
:
d = {
'AAA':['a', 'b', 'c'],
'BBB':['b', 'c', 'd'],
'CCC':['d', 'e', 'f', 'h', 'x'],
'DDD':['d', 'f', 'g'],
'EEE':['g','d','h','o']
}
dict
的值是项。
我想让商品组涵盖所有dict
键。
即('b', 'c')
组存在于AAA
和BBB
中。因此,该组可以覆盖AAA
和BBB
。
可能的结果如下。
{('b', 'c'): ['AAA', 'BBB'],
('d', 'f'): ['CCC', 'DDD'],
('d', 'g'): ['EEE', 'DDD'],}
所有AAA
,BBB
,CCC
,DDD
,EEE
都可以用('b', 'c')
,('d', 'f')
和{ {1}}。
FP-Growth和Apriori算法可能起作用。我如下尝试了('d', 'g')
,但仍然无法获得这样的结果。
FP-Growth
输出为
import pyfpgrowth
d = [
['a', 'b', 'c'],
['b', 'c', 'd'],
['d', 'e', 'f', 'h', 'x'],
['d', 'f', 'g'],
['g','d','h','o']
]
#Use find_frequent_patterns to find patterns in baskets that occur over the support threshold:
patterns = pyfpgrowth.find_frequent_patterns(d, 2)
print(patterns)
FP-Growth和Apriori算法不能直接解决问题。除此之外,他们的表现也不佳。
我们有任何算法或lib可以执行此类任务吗?
答案 0 :(得分:0)
这是使用熊猫的可能解决方案。 可以将包含键的组的长度限制在最小值和最大值之间。
import pandas as pd
d = {
'AAA':['a', 'b', 'c'],
'BBB':['b', 'c', 'd'],
'CCC':['d', 'e', 'f', 'h', 'x'],
'DDD':['d', 'f', 'g'],
'EEE':['g','d','h','o']
}
for k, i in d.items():
df1 = pd.DataFrame(columns=list(i), index=[k])
df1[:]=True
try:
df=df.append(df1, sort=True)
except:
df=df1.copy()
只要知道发生了什么,中间数据帧df就是这样的表:
a b c d e f g h o x
AAA True True True NaN NaN NaN NaN NaN NaN NaN
BBB NaN True True True NaN NaN NaN NaN NaN NaN
CCC NaN NaN NaN True True True NaN True NaN True
DDD NaN NaN NaN True NaN True True NaN NaN NaN
EEE NaN NaN NaN True NaN NaN True True True NaN
然后,您将转置此数据框并提取组,如下面的代码所示;您可以为每个键组中所需的项数设置限制。 覆盖每个组的元素数量没有限制。因此,一组键可以被单个元素(结果)覆盖。 这是一个可能的解决方案,因为除非指定了其他约束,否则您的问题还有很多其他解决方案。 该代码还检查了所有键是否都受给定约束的解决方案覆盖。
# set min and max number of items in each tuple of keys
min = 2
max = 3
df=df.fillna(False)
dft=df.transpose()
dft['sum'] = dft[:].sum(axis=1)
dft1 = dft[(dft['sum']>=min) & (dft['sum']<=max)]
dft1 = dft1.drop('sum', axis=1)
g = lambda a,b:[x for x, y in zip(tuple(a), tuple(b)) if y == True]
c=dft1.columns
dft1['groups'] = dft1.apply(lambda x: g(c, x), axis=1)
dft1['groups'] = dft1['groups'].apply(tuple)
grouped=dft1.groupby('groups')
final = dict()
key_covered = []
for key, item in grouped:
lkey = list(key)
if not set(lkey).issubset(key_covered):
final[key] = tuple(item.index)
key_covered += key
print('Result:')
for k,i in final.items():
print(i, end=': ')
print(k)
print('Keys covered')
print(key_covered)
# Check if result covers all keys
if not set(key_covered).issubset(d.keys()):
print('Initial dict is not covered with this constrains')
每个键组中的最小项目数等于2,最大数量为3,最终结果将是:
Result:
('b', 'c'): ('AAA', 'BBB')
('f',): ('CCC', 'DDD')
('h',): ('CCC', 'EEE')
Keys covered
['AAA', 'BBB', 'CCC', 'DDD', 'CCC', 'EEE']
如果每个键组中的最小项目数等于2,最大数量等于4,则最终结果将是:
Result:
('b', 'c'): ('AAA', 'BBB')
('d',): ('BBB', 'CCC', 'DDD', 'EEE')
Keys covered
['AAA', 'BBB', 'BBB', 'CCC', 'DDD', 'EEE']