我有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”和一些其他的东西都试过,但无法管理到那里。 我明白与任何种类的软编码的解决方案。
答案 0 :(得分:0)
您可以做这个任务用的单指令:
pd.merge(df1, df2, on=['char1', 'char2'])[['group', 'unit', 'result']]
merge
(并不奇怪)将df1
和df2
合并,但结果包含
还有char1
,char2
,char3_x
和char3_y
列,
所以你需要“限制”输出到你想要的列。
请注意,结果列列表位于双方括号中 (您可能会说:一个怪异的符号)。
原因是:
和一点点的话就您的预期输出:
在最后的 “你” 行(B,U2,1102)不应实际包括在内。
注意,在倒数第二个行df2
(C3,中,R,1102)中包含
C3
为char1
,Medium
为char2
,但是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
即三行包含C1
,Large
和U
,另外三行
含有C2
,Medium
和R
。
为了执行过滤您在您的评论解释的方式,
你必须分裂df1
为2个DataFrames:
df1a
containig在char3
,滴char3
列空字符串
(其理由解释如下),df1b
在char3
中包含非空字符串。要做到这一点运行:
df1a = df1.query('char3.str.len() == 0').drop('char3', axis=1)
df1b = df1.query('char3.str.len() > 0')
然后,你应该连接两个部分合并:
df1a
与df
,使用默认的合并准则 - 所有公共列
(char1
和char2
,因此现在很清楚为什么我们放弃了char3
),df1b
与df
再次出现-在所有公用列上(这次是char1
,char2
和char3
),group
,unit
和result
列。要做到这一点运行:
pd.concat([pd.merge(df1a, df2), pd.merge(df1b, df2)])[['group', 'unit', 'result']]