首页 > 解决方案 > 在 python 中创建随机组分配

问题描述

我有一个 Python 脚本,可以根据性能对滑雪者进行排名(列:“GJENNOMSNITT”),然后在 GJENNOMSNITT 上创建两个匹配的组:group1 和 group 2。为此,我使用以下代码:

    def allokereGrupper(df1):
        df1 = df1.sort_values(by='GJENNOMSNITT', ascending=True)
        mask = np.arange(len(df1)) % 2
        group1 = df1.loc[mask == 0]
        print("gruppe 1:")
        print(group1)
        group2 = df1.loc[mask == 1]
        print("gruppe 2:")
        print(group2)
        return group1,group2

这个脚本的问题是最好的滑雪者总是在第 1 组,因为掩码 == 0。相反,我希望这是随机的。我已经用 JavaScript 编码了 4 个月,但我无法在 Python 中为这个问题提出一个好的解决方案。有人能帮我吗?

这是我的所有代码,您应该可以访问我正在阅读的 csv 文件

结果.py

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

class Resultat:

    def lastInnOgRydd(path, LagreCsv = False):
        df = pd.read_csv(path, skiprows=2, decimal=".")
        filt = df['FINISH'] == 'DNF'
        dnf = df[filt]
        dnf = dnf.replace('DNF', 1)
        if LagreCsv == True:
            dnf.to_csv('DNF.csv')
        df.replace('DNF', np.NaN, inplace=True)
        df.replace('GARBAGE GARBAGE', np.NaN, inplace=True) #Denne finnes det nok en bedre løsning på
        df.dropna(subset=['FINISH'], inplace=True)
        df.dropna(subset=['NAME'], inplace=True)
        return df

    def endreDataType(df):
        df["FINISH"] = df["FINISH"].str.replace(',', '.').astype(float)
        df["INTER 1"] = df["INTER 1"].str.replace(',', '.').astype(float)
        df["SECTION IM4-FINISH"] = df["SECTION IM4-FINISH"].str.replace(',', '.').astype(float)
        df["COMMENT"] = df['COMMENT'].astype(int)
        df["COMMENT"] = df['COMMENT'].astype(str)
        df["COMMENT"] = df['COMMENT'].str.replace('11', 'COURSE 1')
        df["COMMENT"] = df['COMMENT'].str.replace('22', 'COURSE 2')
        df["COMMENT"] = df['COMMENT'].str.replace('33', 'COURSE 3')
        df["COMMENT"] = df['COMMENT'].str.replace('55', 'UTKJORING')
        df["COMMENT"] = df['COMMENT'].str.replace('99', 'STRAIGHT-GLIDING')
        pd.to_numeric(df['FINISH'], downcast='float', errors='raise')
        pd.to_numeric(df['INTER 1'], downcast='float', errors='raise')
        pd.to_numeric(df['SECTION IM4-FINISH'], downcast='float', errors='raise')
        return df

    def navnendringCommentTilCourse(df):
        df.rename(columns={'COMMENT': 'COURSE'}, inplace=True)
        return df

    def finnBesteRunder(df):
        grupper = df.groupby(['BIB#', 'COURSE'])
        bestruns = grupper['FINISH'].apply(lambda x: x.nsmallest(2).mean()).reset_index()
        print(bestruns)
        df1 = bestruns.pivot('BIB#', 'COURSE', 'FINISH').reset_index()
        df1['GJENNOMSNITT'] = df1['COURSE 1'].add(df1['COURSE 2']).add(df1['COURSE 3']).div(3)
        #df1['PRESTASJON'] = df1['MEAN'].div(df1['STRAIGHT-GLIDING']) # fjerner denne nå, men må med i den ordentilige analysen
        return df1

    def allokereGrupper(df1):
        df1 = df1.sort_values(by='GJENNOMSNITT', ascending=True)
        mask = np.arange(len(df1)) % 2
        group1 = df1.loc[mask == 0]
        print("gruppe 1:")
        print(group1)
        group2 = df1.loc[mask == 1]
        print("gruppe 2:")
        print(group2)
        return group1,group2

主文件

from moduler import Resultat

path = "http://www.cmagelssen.no/pilot2.csv"

df = Resultat.lastInnOgRydd(path)
df = Resultat.endreDataType(df)
df = Resultat.navnendringCommentTilCourse(df)
df = Resultat.finnBesteRunder(df)
df = Resultat.allokereGrupper(df)

标签: pythonpandas

解决方案


因此,您希望两组匹配,因为对于排名列表 ( ) 中的每一对连续滑雪者,df1将随机(以相等的概率)决定是否将排名较高的滑雪者分配到第 1 组,而排名较低的滑雪者一个到第 2 组,反之亦然。

实现此目的的一种直接(如果不是最有效)的方法是使用 Python 的标准模块在将重复的 0-1 序列分配给 之后random对每对值进行洗牌:maskmask

import numpy as np
import random


def allokereGrupper(df):
    df = df.sort_values(by='GJENNOMSNITT', ascending=True)
    mask = np.arange(len(df)) % 2
    
    # new: for each pair of mask values, 
    #      randomly decide whether to swap them or not
    for i in range(0, len(df), 2):
        random.shuffle(mask[i:i+2])
    
    group1 = df.loc[mask == 0]
    print("gruppe 1:")
    print(group1)
    group2 = df.loc[mask == 1]
    print("gruppe 2:")
    print(group2)
    return group1, group2

请注意,我将参数的名称更改为df,以更明确地表明这是一个通用函数。为了使其更通用,您也可以将要排序的列的名称作为参数传递。


推荐阅读