首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Python计算合同桥接分数的elasticsearch json对象的元素

使用Python计算合同桥接分数的elasticsearch json对象的元素
EN

Stack Overflow用户
提问于 2018-12-25 02:03:10
回答 2查看 277关注 0票数 7

数据在这里:

代码语言:javascript
复制
{'took': 0, 'timed_out': False, '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0}, 'hits': {'total': 16, 'max_score': 1.0, 'hits': [{'_index': 'matchpoints', '_type': 'score', '_id': '6PKYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '1', 'nsp': '4', 'ewp': '11', 'contract': '3NT', 'by': 'N', 'tricks': '11', 'nsscore': '460', 'ewscore ': '0'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '7_KYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '2', 'nsp': '3', 'ewp': '10', 'contract': '3C', 'by': 'E', 'tricks': '10', 'nsscore': '-130', 'ewscore ': '130'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '6fKYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '1', 'nsp': '5', 'ewp': '12', 'contract': '3NT', 'by': 'S', 'tricks': '10', 'nsscore': '400', 'ewscore ': '0'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '8_KYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '2', 'nsp': '7', 'ewp': '14', 'contract': '3C', 'by': 'E', 'tricks': '10', 'nsscore': '-130', 'ewscore ': '130'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '9PKYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '2', 'nsp': '8', 'ewp': '15', 'contract': '3C', 'by': 'E', 'tricks': '11', 'nsscore': '-150', 'ewscore ': '150'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '5fKYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '1', 'nsp': '1', 'ewp': '16', 'contract': '3NT', 'by': 'N', 'tricks': '10', 'nsscore': '430', 'ewscore ': '0'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '6vKYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '1', 'nsp': '6', 'ewp': '13', 'contract': '4S', 'by': 'S', 'tricks': '11', 'nsscore': '480', 'ewscore ': '0'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '6_KYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '1', 'nsp': '7', 'ewp': '14', 'contract': '3NT', 'by': 'S', 'tricks': '8', 'nsscore': '-50', 'ewscore ': '50'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '7fKYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '2', 'nsp': '1', 'ewp': '16', 'contract': '6S', 'by': 'N', 'tricks': '12', 'nsscore': '1430', 'ewscore ': '0'}}, {'_index': 'matchpoints', '_type': 'score', '_id': '7vKYGGgBjpp4O0gQgUu5', '_score': 1.0, '_source': {'board_number': '2', 'nsp': '2', 'ewp': '9', 'contract': '3C', 'by': 'E', 'tricks': '10', 'nsscore': '-130', 'ewscore ': '130'}}]}}

包含最新更改的Python代码如下所示。作为我的中间尝试,不会尝试在不同的板之间循环。这些数据是由search all查询生成的。

代码语言:javascript
复制
@application.route('/', methods=['GET', 'POST'])
def index():
    search = {"query": {"match_all": {}}}
    resp = es.search(index="matchpoints", doc_type="score", body = search)
    rows = extract_rows(resp)
    for board in rows:
        scores = score_board(board)
        report(scores)
        print(report(scores))
    return 'ok'

def extract_rows(resp):                                                                                                          
    """Extract the rows for the board from the query response."""                                                                
    # Based on the data structure provided by the OP.                                                          
    rows = [row["_source"] for row in resp["hits"]["hits"]]
    # We want to return the group the data by board number
    # so that we can score each board.                                                                       
    keyfunc = lambda row: int(row['board_number'])                                                                               
    rows.sort(key=keyfunc)                                                                                                       
    for _, group in itertools.groupby(rows, keyfunc):                                                                            
        yield list(group)

def compute_mp(scores, score):
    """Compute the match point score for a pair."""
    mp_score = sum(v for k, v in scores.items() if score > k) * 2
    # The pair's own score will always compare equal - remove it.
    mp_score += sum(v for k, v in scores.items() if score == k) - 1
    return mp_score

def score_board(tables):
    """Build the scores for each pair."""
    scores = []
    top = 2 * (len(tables) - 1)
    # Store the scores for each N-S partnership.
    ns_scores = collections.Counter(int(table["nsscore"]) for table in tables)
    # Build the output for each pair.
    for table in tables:
        output = {
            "board": table["board_number"],
            "nsp": table["nsp"],
            "ewp": table["ewp"],
        }
        ns_score = int(table["nsscore"])
        ns_mp_score = compute_mp(ns_scores, ns_score)
        output["ns_mp_score"] = ns_mp_score
        ew_mp_score = top - ns_mp_score
        output["ew_mp_score"] = ew_mp_score
        scores.append(output)
    return scores

# Replace this function with one that adds the rows to
# the new search index
def report(scores):
    """Print the scores."""
    for row in scores:
        print(row)

它像以前一样产生正确的字典,其中评分是正确的,但是有重复的结果和太多的行。另外,有两个"None“的例子,我不知道这是从哪里来的。:

代码语言:javascript
复制
{'board': '1', 'nsp': '4', 'ewp': '11', 'ns_mp_score': 6, 'ew_mp_score': 2}
{'board': '1', 'nsp': '5', 'ewp': '12', 'ns_mp_score': 2, 'ew_mp_score': 6}
{'board': '1', 'nsp': '1', 'ewp': '16', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '1', 'nsp': '6', 'ewp': '13', 'ns_mp_score': 8, 'ew_mp_score': 0}
{'board': '1', 'nsp': '7', 'ewp': '14', 'ns_mp_score': 0, 'ew_mp_score': 8}
{'board': '1', 'nsp': '4', 'ewp': '11', 'ns_mp_score': 6, 'ew_mp_score': 2}
{'board': '1', 'nsp': '5', 'ewp': '12', 'ns_mp_score': 2, 'ew_mp_score': 6}
{'board': '1', 'nsp': '1', 'ewp': '16', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '1', 'nsp': '6', 'ewp': '13', 'ns_mp_score': 8, 'ew_mp_score': 0}
{'board': '1', 'nsp': '7', 'ewp': '14', 'ns_mp_score': 0, 'ew_mp_score': 8}
None
{'board': '2', 'nsp': '3', 'ewp': '10', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '2', 'nsp': '7', 'ewp': '14', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '2', 'nsp': '8', 'ewp': '15', 'ns_mp_score': 0, 'ew_mp_score': 8}
{'board': '2', 'nsp': '1', 'ewp': '16', 'ns_mp_score': 8, 'ew_mp_score': 0}
{'board': '2', 'nsp': '2', 'ewp': '9', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '2', 'nsp': '3', 'ewp': '10', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '2', 'nsp': '7', 'ewp': '14', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '2', 'nsp': '8', 'ewp': '15', 'ns_mp_score': 0, 'ew_mp_score': 8}
{'board': '2', 'nsp': '1', 'ewp': '16', 'ns_mp_score': 8, 'ew_mp_score': 0}
{'board': '2', 'nsp': '2', 'ewp': '9', 'ns_mp_score': 4, 'ew_mp_score': 4}
None

评分是正确的,但同样也存在相同配对结果重复的多个情况。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-03 00:53:21

这段代码将计算分数。代码相当简单。

不是迭代输入字典来计算每一对的分数,而是将北南分数存储在一个collections.Counter实例中,该实例保存每个分数对的数量的计数。这使得计算每一对的赛点分数变得更容易-我们只需将较低分数的数量增加一倍,然后将相等分数的数量减去1来计算当前合作伙伴的分数。

代码语言:javascript
复制
import collections                                                                                                               
import itertools                                                                                                                                                                                                                                    


def extract_rows(resp):                                                                                                          
    """Extract the rows for the board from the query response."""                                                                
    # Based on the data structure provided by the OP.                                                          
    rows = [row["_source"] for row in resp["hits"]["hits"]]
    # We want to return the group the data by board number
    # so that we can score each board.                                                                       
    keyfunc = lambda row: int(row['board_number'])                                                                               
    rows.sort(key=keyfunc)                                                                                                       
    for _, group in itertools.groupby(rows, keyfunc):                                                                            
        yield list(group)


def compute_mp(scores, score):
    """Compute the match point score for a pair."""
    mp_score = sum(v for k, v in scores.items() if score > k) * 2
    # The pair's own score will always compare equal - remove it.
    mp_score += sum(v for k, v in scores.items() if score == k) - 1
    return mp_score


def score_board(tables):
    """Build the scores for each pair."""
    scores = []

    # Store the scores for each N-S partnership.
    ns_scores = collections.Counter(int(table["nsscore"]) for table in tables)
    # The top score is (2 * number of tables) - 2, then reduced by one for each 
    # equal top score.
    top = 2 * (len(tables) - 1) - (ns_scores[max(ns_scores)] - 1)
    # Build the output for each pair.
    for table in tables:
        output = {
            "board": table["board_number"],
            "nsp": table["nsp"],
            "ewp": table["ewp"],
        }
        ns_score = int(table["nsscore"])
        ns_mp_score = compute_mp(ns_scores, ns_score)
        output["ns_mp_score"] = ns_mp_score
        ew_mp_score = top - ns_mp_score
        output["ew_mp_score"] = ew_mp_score
        scores.append(output)
    return scores

# Replace this function with one that adds the rows to
# the new search index
def report(scores):
    """Print the scores."""
    for row in scores:
        print(row)

运行代码:

代码语言:javascript
复制
rows = extract_rows(resp)
scores = [score for rows in extract_rows(resp) for score in score_board(rows)]
report(scores)

生成以下输出:

代码语言:javascript
复制
{'board': '1', 'nsp': '4', 'ewp': '11', 'ns_mp_score': 6, 'ew_mp_score': 2}
{'board': '1', 'nsp': '5', 'ewp': '12', 'ns_mp_score': 2, 'ew_mp_score': 6}
{'board': '1', 'nsp': '1', 'ewp': '16', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '1', 'nsp': '6', 'ewp': '13', 'ns_mp_score': 8, 'ew_mp_score': 0}
{'board': '1', 'nsp': '7', 'ewp': '14', 'ns_mp_score': 0, 'ew_mp_score': 8}
{'board': '2', 'nsp': '3', 'ewp': '10', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '2', 'nsp': '7', 'ewp': '14', 'ns_mp_score': 4, 'ew_mp_score': 4}
{'board': '2', 'nsp': '8', 'ewp': '15', 'ns_mp_score': 0, 'ew_mp_score': 8}
{'board': '2', 'nsp': '1', 'ewp': '16', 'ns_mp_score': 8, 'ew_mp_score': 0}
{'board': '2', 'nsp': '2', 'ewp': '9', 'ns_mp_score': 4, 'ew_mp_score': 4}
票数 3
EN

Stack Overflow用户

发布于 2019-01-02 23:30:16

这不是我的工作,这是“房车”的工作,但由于这是我正在寻找的答案,我将它张贴在这里,以便可以帮助其他人。

代码语言:javascript
复制
scores = {}
for row in arr["hits"]["hits"]:
  nsp = row["_source"]["nsp"]
  nsscore = row["_source"]["nsscore"]
  scores[nsp] = nsscore

input_scores = {}

def calculate_score(pair, scores):
    score = 0
    for p in scores:
        if p == pair:
            continue
        if scores[p] < scores[pair]:
            score += 2  # win
        elif scores[p] == scores[pair]:
            score += 1
    return score


board_num = arr["hits"]["total"]
top = (board_num - 1) * 2
result_score = {}
for row in arr["hits"]["hits"]:
  nsp = row["_source"]["nsp"]
  ewp = row["_source"]["ewp"]
  res = calculate_score(nsp, scores)
  ew_mp_score = top - res
  result_score.update({'nsp':nsp, 'ns_mp_score': res, 'ewp': ewp, 'ew_mp_score': ew_mp_score})
  print(result_score)

谢谢。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53916503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档