使用另一个数据框的多个列值过滤数据框

时间:2019-02-02 18:33:59

标签: python pandas loops filtering

我有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”和一些其他的东西都试过,但无法管理到那里。 我明白与任何种类的软编码的解决方案。

1 个答案:

答案 0 :(得分:0)

您可以做这个任务用的指令:

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

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

请注意,结果列列表位于方括号中 (您可能会说:一个怪异的符号)。

原因是:

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

和一点点的话就您的预期输出:

在最后的 “你” 行(B,U2,1102)不应实际包括在内。 注意,在倒数第二个行df2(C3,中,R,1102)中包含 C3char1Mediumchar2,但是df1不包含 包含这些值的任何行。

编辑

您写道,您想对所有三个 char1 进行过滤(实际上是合并), char2 char3 列。

大概是:

  • 词典df1应该containt '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个DataFrames:

  • df1a containig在char3,滴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']]