【问题标题】:Filtering a data frame with multiple column values of another data frame [duplicate]过滤具有另一个数据框的多列值的数据框[重复]
【发布时间】:2019-02-03 19:50:40
【问题描述】:

我有 2 个数据框如下:

df1={"group":["A","B"],
 "unit":["U1","U2"],
 "char1":["C1","C2"],
 "char2":["Large","Medium"],
 "char3":["","R"]
}
df1=pd.DataFrame.from_dict(df1)

df2={"char1":["C1","C1","C1","C1","C2","C2","C2","C3","C3"],
"char2":["Large","Large","Large","Large","Medium","Medium","Medium","Medium","Large"],
 "char3":["U","U","U","R","R","R","U","R","R"],
 "result":[113,114,115,116,818,819,1101,1102,1103]}

df2=pd.DataFrame.from_dict(df2)

我想用 df1 列 (char1,char2,char3) 的值过滤 df2。 最后,对于 df1 中的每个 group_unit 对,我想分配来自 df2 的过滤结果。

所需的输出如下所示:

output={"group":["A","A","A","A","B","B"],
    "unit" :["U1","U1","U1","U1","U2","U2"],
    "result":[113,114,115,116,818,819]}
output=pd.DataFrame.from_dict(output)

我尝试过使用“isin”和其他一些东西,但无法到达那里。 我很欣赏任何类型的软编码解决方案。

【问题讨论】:

  • 如果你想对 char1 char2 和 char3 进行“过滤”,你的输出不正确
  • @Chris,你是对的。我更正了示例输出。感谢您的警告。

标签: python pandas loops filtering


【解决方案1】:

您可以通过单个指令完成此任务:

pd.merge(df1, df2, on=['char1', 'char2'])[['group', 'unit', 'result']]

merge(毫不奇怪)合并了df1df2,但结果包含 还有char1char2char3_xchar3_y 列, 所以你需要将输出“限制”到你想要的列。

注意,结果列列表在方括号中 (你可能会说:一个奇怪的符号)。

原因是:

  • “外部”对是索引的“正常”对,
  • 但是因为我们有一个列表而不是单个列名 列名,必须用另一对方括号括起来。

关于您的预期输出的一点评论:

实际上不应包含最后一个“您的”行(B、U2、1102)。 请注意,df2 (C3, Medium, R, 1102) 中的最后一行包含 C3 作为char1Medium 作为char2,但df1 不包含 包含这些值的任何行。

编辑

您写道要过滤(实际上是合并)所有三个 char1char2char3 列。

所以可能:

  • df1 的字典应包含 'char3':['U', 'R'](注意添加的“U”)。
  • merge 指令应该是:pd.merge(df1, df2)(默认合并 所有公共列的标准),“[[...]]”部分与以前一样。

那么结果将包含:

  group unit  result
0     A   U1     113
1     A   U1     114
2     A   U1     115
3     B   U2     818
4     B   U2     819
5     B   U2    1101

即三行包含 C1LargeU 以及另外三行 包含C2MediumR

编辑 2

为了按照您在评论中解释的方式执行过滤, 您必须将 df1 拆分为 2 个 DataFrame:

  • df1achar3 中包含一个空字符串,删除 char3 列 (原因在下面解释),
  • df1bchar3 中包含非空字符串。

要运行:

df1a = df1.query('char3.str.len() == 0').drop('char3', axis=1)
df1b = df1.query('char3.str.len() > 0')

那么你应该连接两个部分合并:

  • df1adf,使用默认合并标准 - 所有公共列 (char1char2,所以现在很清楚为什么我们放弃了 char3),
  • df1bdf,再次出现在所有常用列上(这次是 char1char2char3),
  • 只留下groupunitresult 列。

要运行:

pd.concat([pd.merge(df1a, df2), pd.merge(df1b, df2)])[['group', 'unit', 'result']]

【讨论】:

  • 您对所需输出的评论是正确的。我更正了,谢谢。我还对 df2 进行了更明确的编辑。当谈到您对 df1 的评论时,我故意创建了 'char3':[' ', 'R'] 。因为如果 char 值为空白/null,我希望代码将所有结果置于“char3”下。例如,A_U1 对应该得到所有可能的结果 (113,114,115,116),因为没有为此对指定“char3”标准。最后一点:您的解决方案中没有使用任何 char3 。但是,B_U2 对建议“char3”标准的“R”。考虑到这些,您将如何编写代码?
猜你喜欢
  • 2020-11-16
  • 1970-01-01
  • 1970-01-01
  • 2018-11-12
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 2017-06-28
  • 2022-01-22
相关资源
最近更新 更多