我有 2 个这样的 CSV 文件,想通过匹配两个数据帧中的列(测试,cond)来更新基于 df2(LL,UL) 的 df1 列 (LL,UL)
df1:
test Cond day mode LL UL
a T1 Tue 7
b T2 mon 7
c T2 sun 6
d T3 fri 3
c T2 sat 6
d T3 wed 3
df2:-
test Cond LL UL
a T1 15 23
b T2 -3 -3.5
c T2 -19 -11
d T3 6.5 14.5
我的预期输出应该是:-
def SpecsLL(cond1,test1):
if ((cond1==spec['Cond'] ) & (test1==spec['test'])):
return df2['LL']
df1['LL'] = df1.apply(lambda x: SpecsLL(x['Cond'],x['test']),axis=1)
我已经尝试过上面的代码但没有工作。
关于如何做到这一点的任何想法??
答案 0 :(得分:0)
combine_first
index_cols = ['test', 'Cond']
(
df1
.set_index(index_cols)
.combine_first(
df2.set_index(index_cols)
).reset_index()
)
说明:
set_index
将指定的列移动到索引中,表示每一行都应由其 test
和 Cond
列标识。foo.combine_first(bar)
将识别 foo
和 bar
之间匹配的索引 + 列标签,并在 bar
为 NaN 或有列的任何地方填充 foo
中的值/行丢失。在这种情况下,由于 set_index
,两个数据帧的行将匹配,其中 test
和 Cond
相同,然后 UL
和 {{1} } LL
中的值将填充到输出的相应列中。df2
只是反转 reset_index
调用,使 set_index
和 test
再次成为常规列。请注意,此操作可能会破坏列的顺序,因此如果这对您很重要,那么您可以在最后调用 Cond
,这会将列重新排序为 .reindex(df1.columns, axis=1)
中的原始顺序.
df1
或者,您可以使用 merge
方法,该方法允许您直接对列进行操作而无需使用 merge
,但需要一些其他预处理:
set_index
index_cols = ['test', 'Cond']
(
df1
.drop(['LL', 'UL'], axis=1)
.merge(
df2,
on=index_cols
)
)
调用是必要的,否则 .drop
将在输出中包含来自两个 DataFrame 的 merge
和 UL
列:
LL
根据您提供的数据, test Cond day mode LL_x UL_x LL_y UL_y
0 a T1 Tue 7 NaN NaN 15.0 23.0
1 b T2 mon 7 NaN NaN -3.0 -3.5
2 c T2 sun 6 NaN NaN -19.0 -11.0
3 c T2 sat 6 NaN NaN -19.0 -11.0
4 d T3 fri 3 NaN NaN 6.5 14.5
5 d T3 wed 3 NaN NaN 6.5 14.5
似乎是更自然的操作 - 如果您从不期望 UL 和 LL 在 merge
中有任何数据,那么如果可能我建议简单地从输入 CSV 中完全删除这些列标题,以便 df1
根本没有这些列。在这种情况下,将不再需要 df1
调用,并且所需的 drop
调用非常具有表现力。
但是,如果您希望 merge
有时具有 df1
或 UL
的实际值,并且您希望在输出中包含这些值,那么 LL
解决方案就是你想要的。请注意,如果 combine_first
和 df1
对于特定行/列具有不同的非空值,则 df2
将从 df1.combine_first(df2)
中选择值并忽略 {{ 1}} 值。如果您想优先处理来自 df1
的值,那么您可以反过来调用它,即 df2
。
答案 1 :(得分:0)
只需使用熊猫的合并功能
df1.merge(df2)