我想基于和多行列上的条件从熊猫数据框中的一列中选择(唯一)值。考虑以下示例数据帧:
df = pd.DataFrame({'Developer': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'],
'Language': ['Java', 'Python', 'Python', 'Java', 'Python', 'Python', 'Java', 'Python', 'C++'],
'Skill_Level': [1, 3, 3, 3, 2, 3, 3, 1, 3],
'Version': ["x.x", "2.x", "3.x", "x.x", "2.x", "3.x", "x.x", "3.x", "x.x"]
})
Developer Language Skill_Level Version
0 A Java 1 x.x
1 A Python 3 2.x
2 A Python 3 3.x
3 B Java 3 x.x
4 B Python 2 2.x
5 B Python 3 3.x
6 C Java 3 x.x
7 C Python 1 3.x
8 C C++ 3 x.x
现在,我想找到所有了解Java且技能水平至少为3的开发人员,并且也知道Python(无论版本如何)至少具有2级的技能。
我现在解决该问题的方法是,根据Java条件选择一组,然后根据Python条件选择另一组,然后进行内部合并以获取符合所有条件的开发人员:
result_java_df = df[(df["Language"] == "Java") & (df["Skill_Level"] >= 3)][["Developer"]]
result_python_df = df[(df["Language"] == "Python") & (df["Skill_Level"] >= 2)][["Developer"]]
result_df = result_java_df.merge(result_python_df, on="Developer")
result_df = result_df.drop_duplicates()
Developer
0 B
是否有更“优雅”的方式来做到这一点?我感觉自己在忽略水木清华。特别是如果我想基于更多基于行的条件进行选择(例如选择以某种技能水平了解四种语言的开发人员),这将变得很复杂,当然可以证明编写处理此类选择的函数是合理的。因此,我想知道熊猫是否以某种方式支持此功能,而我只是没有找到该功能。
答案 0 :(得分:4)
我跑步时
qualified= df.groupby("Developer").apply(
lambda x:
any(
(x.Language == "Java") &
(x.Skill_Level >=3)
) &
any(
(x.Language == "Python") &
(x.Skill_Level >= 2))
)
我知道了
Developer
A False
B True
C False
dtype: bool
然后可以使用各种方法(例如
)进行子集化[developer for developer,status in qualified.items() if status]
(返回列表)
或
qualified[qualified]
(返回系列)
如果要使其更通用,可以执行以下操作:
minimum_skill_levels = {"Java":3,
"Python":2}
qualified= df.groupby("Developer").apply(
lambda x:
all([any(
(x.Language == Language)&
(x.Skill_Level >= Skill_Level)
)
for Language, Skill_Level in minimum_skill_levels.items()
])
)
答案 1 :(得分:0)
好吧,多亏了pandas的多索引功能,我还是可以正常工作,但从正面来看,它还不错,没有循环,没有lambda。我认为这是最佳做法,因为它使用切片和索引,并且一旦数据正确格式化(正确的索引和列),性能也应该会更好。
import pandas as pd
idx = pd.IndexSlice
df_p = df.pivot_table(index = 'Language', columns = 'Developer')
java = df_p.loc['Java'] >= 3
python = df_p.loc['Python'] >= 2
df_p.loc[:, idx[:, java & python]]
将适当的开发者输出为一列
df_p.loc[:, idx[:, java & python]]['Skill_Level'].columns.tolist()
如果以后需要它们,则将它们列出在列表中。