你必须原谅我,因为我目前正在学习Python。我有一个包含以下工作人员属性列的Pandas
DataFrame
:姓名、职位、小时工资。
东风
Index Name Position HourlyPay
0 John Analyst 15.00
1 Mike Programmer 18.00
2 Lisa Supervisor 16.75
4 Frank Analyst 15.50
我想输出到另一个DataFrame
(如下所示),其中包含n
个人团队的所有可能的独特组合,其中还包括他们的 位置作为列标题,另一列汇总其HourlyPay
,然后按最高TotalHourlyPay
排序。
独特的Df
Index Analyst Programmer Supervisor TotalHourlyPay
0 Frank Mike Lisa 50.25
1 John Mike Lisa 49.75
我在上面uniqueDf
示例中使用了 3 个位置,但有时这可能会改变。例如,2 个Analyst
职位可以同时工作,因此我希望在需要时可以选择动态添加或删除多个职位列。第二个例子如下。
第二个示例Df
Index Analyst Analyst Programmer Supervisor TotalHourlyPay
0 Frank John Mike Lisa 65.25
这是一个非常简单的数据集示例。我已经尝试过这个问题,但我的代码并不值得展示。我得到的最接近的是df.Name
列上使用itertools.combinations
。我试图通过在两个DataFrame
之间使用join
或merge
来附加和TotalHourlyPay
列,但我也无法做到这一点。
possibleCombinations = list(itertools.combinations(df.Name, 3))
uniqueDf = pd.DataFrame(possibleCombinations,columns=['Employee1','Employee2','Employee3'])
我真的只是问是否有人可以帮助我指出正确的方向。我知道SO不是为你编写代码,我绝对不想要。我真的只是对下一步该怎么做感到困惑,谷歌浏览器上的每个链接都会从点击中突出显示。任何帮助将不胜感激。
谢谢
此代码给出您想要的结果:
import pandas as pd
import itertools
# definition of dataframe
df = pd.DataFrame()
df["Index"] = [0, 1, 2, 4, 5, 6, 8, 9, 10]
df["Name"] = ["John", "Mike", "Lisa", "Franck", "Peter", "Suzanne", "Laura", "Sam", "Manon"]
df["Position"] = ["Analyst", "Programmer", "Supervisor", "Analyst", "Programmer", "Programmer", "Supervisor", "Analyst", "Analyst"]
df["HourlyPay"] = [15.00, 18.00, 16.75, 15.50, 17.00, 18.00, 16.00, 12.00, 13.00]
# dict of dataframes by position
unique_positions = list(df["Position"].unique())
pos_dfs = {}
for pos in unique_positions:
pos_dfs[pos] = df.loc[df["Position"]==pos].reset_index()
# required positions with count
req_pos_count = pd.DataFrame.from_dict({"count":{"Analyst": 2, "Supervisor": 1, "Programmer": 1}})
req_pos_unique = list(req_pos_count.index.unique())
req_pos_dfs = [pos_dfs[pos] for pos in req_pos_unique]
which_pos = [item for _, row in req_pos_count.iterrows() for item in [row.name]*row["count"]]
which_pos_count = [str(i) + "_" + pos for i, pos in enumerate(which_pos)]
# combinations
pos_dfs_rows = [list(itertools.combinations(range(len(pos_df)), req_pos_count.loc[req_pos_unique[i]]["count"]))
for i, pos_df in enumerate(req_pos_dfs)]
pos_dfs_rows_comb = [[it for item in sublist for it in item]
for sublist in list(itertools.product(*pos_dfs_rows)) ]
# building of result
uniqueDf = pd.DataFrame(index=range(len(pos_dfs_rows_comb)), columns=which_pos_count+["TotalHourlyPay"])
for k, comb in enumerate(pos_dfs_rows_comb):
rows = [pos_dfs[which_pos[i]].ix[ind] for i, ind in enumerate(comb)]
tp = pd.concat(rows, axis=1, ignore_index=True).transpose()
uniqueDf.loc[k, which_pos_count] = list(tp["Name"])
uniqueDf["TotalHourlyPay"].loc[k] = tp["HourlyPay"].sum()
uniqueDf.sort_values(by="TotalHourlyPay", inplace=True)
这是我遵循的过程。
首先,获取持有或缺失仓位的指标变量:
position = pd.get_dummies(df['Position']).astype(bool)
not_position = ~pd.get_dummies(df['Position'], prefix='not').astype(bool)
df1 = pd.concat([df, position, not_position], axis=1)
接下来,生成可能的组合:
df2 = df1.merge(df1, left_on='Programmer', right_on='not_Programmer', suffixes=['', '_y'])
df3 = df2.merge(df1, left_on='Supervisor', right_on='not_Supervisor', suffixes=['', '_z'])
然后,删除重复项并提取仍然相关的字段
df4 = df3[(df3['Analyst']) & (df3['Programmer_y']) & (df3['Supervisor_z'])]
df4.loc[:, ['Name', 'Name_y', 'Name_z', 'HourlyPay', 'HourlyPay_y', 'HourlyPay_z']]
Name Name_y Name_z HourlyPay HourlyPay_y HourlyPay_z
0 John Mike Lisa 15.0 18.0 16.75
1 Frank Mike Lisa 15.5 18.0 16.75
之后,您可以跨行获取总和,删除新无用的支付列,并重命名剩余的列以返回类似于 uniqueDf 的输出。