Python 碰到一题,大家有没有更好的解法

2021-07-22 21:17:12 +08:00
 wuwukai007
nput_data = [
    ['格力', '格力电器'],
    ['格力', '美的', '格力电器', '美的集团'],
    ['中国民生投资股份有限公司', '中民投'],
    ['格力', '格力电器', '格力集团'],
    ['工银', '中信证券', '工行', '中国工商银行'],
    ['建行', '建设银行', '北大光华'],
    ['中国银行', '工行', '工商银行', '港交所'],
    ['中行', '建行', '工行', '中金', '工商银行', '中国银行', '建设银行'],
    ['农行', '建设银行', '建行', '中行'],
    ['中国民生投资股份有限公司', '上海金融法院', '中民投', '启信宝']
]
输出:
            {('格力', '格力电器'): 3,
             ('美的', '美的集团'): 1,
             ('中民投', '中国民生投资股份有限公司'): 2,
             ('格力', '格力集团'): 1,
             ('工银', '中国工商银行'): 1,
             ('建行', '建设银行'): 3,
             ('中行', '中国银行'): 2,
             ('工银', '工商银行'): 2}


from itertools import chain
from collections import defaultdict

data = list(chain(*nput_data))
res = [set(i) for i in data]

count = defaultdict(int)
for index,row in enumerate(res):
    for index2,i in enumerate(res):
        if row.issuperset(i) and row != i:
            count[(data[index2],data[index])] += 1
            break
        
3047 次点击
所在节点    Python
21 条回复
imn1
2021-07-22 22:02:53 +08:00
问题:
这些 key 是怎么定的?例如"工银","工商银行"这个 2 是怎么出来的?还分词么?
wuwukai007
2021-07-22 22:05:10 +08:00
@imn1 key1 全包含 key2 就算一类,例如 '中国民生投资股份有限公司' 包含 '中民投'
noparking188
2021-07-22 22:10:56 +08:00
麻烦把原题贴出来,连定义都没有
wuwukai007
2021-07-22 22:17:07 +08:00
@noparking188 原题就是 nput_data = [xx] ,结果是: ('格力', '格力电器'): 3, ('格力', '格力集团'): 1,, 等,请补全结果,我也是嗯做,然后说是 key 全包含另一个 key 作为一个分类,统计所有分类数量
menc
2021-07-22 22:17:39 +08:00

from itertools import combinations
生成所有组合数,避免自己手写,但是顺序不固定,记得用长度 sort 一下
menc
2021-07-22 22:18:13 +08:00
from itertools import combinations
from collections import defaultdict

result = defaultdict(int)
for line in nput_data:
combs = combinations(line, 2)
for comb in combs:
comb_ = sorted(comb, key=lambda x:len(x))
if set(comb_[1]).issuperset(set(comb_[0])):
result[tuple(comb_)] += 1
menc
2021-07-22 22:18:26 +08:00
```python
from itertools import combinations
from collections import defaultdict

result = defaultdict(int)
for line in nput_data:
combs = combinations(line, 2)
for comb in combs:
comb_ = sorted(comb, key=lambda x:len(x))
if set(comb_[1]).issuperset(set(comb_[0])):
result[tuple(comb_)] += 1
```
menc
2021-07-22 22:18:46 +08:00
不支持贴代码啊。。。
理解思想好了(
wuwukai007
2021-07-22 22:19:41 +08:00
@menc 谢谢。我看下 combinations 怎么用,没用过
imn1
2021-07-22 22:41:27 +08:00
key 肯定要另外算,值反而是小事,key 出来后 groupby,count 一下就行了
imn1
2021-07-22 22:52:27 +08:00
('工银', '工商银行'): 2
这个如果没有写错的话,是最大问题,如果是'工行',那还可以理解为每行行内匹配|组合
如果是'工银'无误,那就变成跨行匹配了('工银'只出现一次,这个 2 搞得很混乱,不知道怎么来的),跨行匹配就应该有 ('中国银行', '中国工商银行') 这种组合

有些细则没有写明,例如第一个 key 是否有字数限制,能否跨行匹配等等
O5oz6z3
2021-07-23 02:15:53 +08:00
不知道对不对,花里胡哨做法两则如下:
exec('''
from itertools import chain
from collections import Counter
from pprint import pprint as pp

# from functools import lru_cache
# _set = lru_cache(None)(set)
# issupset = lambda x,y: _set(x).issuperset(_set(y)) and x!=y

# nput_data = ……
issupset = lambda x,y: set(x).issuperset(set(y)) and x!=y
all = list(chain.from_iterable(nput_data))
any = set(all)

print('如果不重复匹配')
hits = []
for x in all:
\t for y in any:
\t\t if issupset(x, y):
\t\t\t hits.append((y, x))
\t\t\t break
pp(Counter(hits))

print('如果重复匹配')
from itertools import product
res = filter(lambda a:issupset(*a), product(all, any))
ctr = Counter((y,x) for x,y in res)
pp(ctr)
''')
<del>(答对有奖吗)</del>
Xs0ul
2021-07-23 03:59:48 +08:00
需求不明确,打回去重写(

但作为一个需求,看起来是根据上下文,找出缩写。缩写就定义成每个字都在另一个字符串中。然后统计所有缩写的数量
ericgui
2021-07-23 06:50:31 +08:00
你就遍历呗,性能再差能差到哪里
zzl22100048
2021-07-23 08:09:00 +08:00
按字拆分取倒排索引,查询的时候取交集
wuwukai007
2021-07-23 08:14:16 +08:00
@O5oz6z3 没有呢😀
O5oz6z3
2021-07-23 08:20:48 +08:00
@wuwukai007 啊这,所以答对了?
wuwukai007
2021-07-23 09:29:31 +08:00
@O5oz6z3 没有标准答案啊,只有最优解
O5oz6z3
2021-07-23 09:40:15 +08:00
@wuwukai007 好吧,那最后一个问题,题目是要求 key1 只能匹配一种 key2 ?还是说 key1 可以匹配多种 key2 ?比如 “中国工商银行” 可以分类到 “工银”、“中行” 或者 “工行” 等等。
araraloren
2021-07-23 10:55:02 +08:00
感觉比较科学的就是 按 顺序 和 单字 来匹配.. 毕竟缩写的字不一定相连

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/791154

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX