置换值熊猫数据框

时间:2020-05-18 00:18:55

标签: python pandas numpy

我有一个数据框,索引中的人名,列中的水果名,值是从人到水果的距离。像这样

(index)   apple  orange  lemon  grape
John      22.3   13.1    14.9   8.8
Mike      12.1   14.2    11.3   5.3
Kevin     9.13   14.9    3.3    22.3
Leon      11.9   13.2    7.14   21.1
Joe       1.15   23.12   11.11  3.18
Frank     4.13   4.13    3.12   29.3
Ralph     7.8    23.1    14.4   29.0

一个人只能摘一个水果,我需要找出总体最小距离(所以我需要将所有组合的总距离相加,然后找出最小的距离)以及每个水果的摘取者的名字。

解决此问题的最佳方法是使用itertools.permutation?

1 个答案:

答案 0 :(得分:0)

假设您需要每个水果都由不同的人采摘,则可以使用itertools来评估名称和水果的所有可能组合,但这对于较大的问题将是棘手的。

典型的解决方案是使用Integer Programming。 Python有许多可以帮助您解决IP问题的库。例如,以下是使用CVXPY库解决您的问题的方法:

import numpy as np
import pandas as pd
import cvxpy as cp
from io import StringIO

data = """name   apple  orange  lemon  grape
John      22.3   13.1    14.9   8.8
Mike      12.1   14.2    11.3   5.3
Kevin     9.13   14.9    3.3    22.3
Leon      11.9   13.2    7.14   21.1
Joe       1.15   23.12   11.11  3.18
Frank     4.13   4.13    3.12   29.3
Ralph     7.8    23.1    14.4   29.0"""
df = pd.read_csv(StringIO(data), sep="\s+", index_col=0)

# Define the decision variable as a matrix of boolean values with 
# len(names) rows and len(fruits) columns
x = cp.Variable(shape=(len(df.index), len(df.columns)), boolean=True)

# Define the objective function as the sum distances
objective = cp.sum(cp.multiply(df.values, x))

# Constrain the problem so that each person picks a single fruit 
# and each fruit is picked by someone
constraint1 = cp.sum(x, axis=0) == 1
constraint2 = cp.sum(x, axis=1) <= 1

# Define the problem and fins solution
problem = cp.Problem(cp.Minimize(objective), [constraint1, constraint2])
problem.solve()

结果是:

>>> x.value.round()
array([[0., 0., 0., 0.],
       [0., 0., 0., 1.],
       [0., 0., 1., 0.],
       [0., 0., 0., 0.],
       [1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 0., 0.]])

意思是Joe摘了苹果,Frank摘了橙,Kevin摘了柠檬,Mike摘了葡萄。