基于另一个表更新数据框中的多列

2024-09-30 18:33:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个类似这样的CSV文件,希望通过匹配两个数据帧中的列(test,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  

我的预期产出应该是:-

enter image description here

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)

我尝试了上述代码,但没有成功。
有什么办法吗


Tags: 文件csvtestuldf1t1t3df2
2条回答

只需使用熊猫的合并功能

df1.merge(df2)

方法1:combine_first

index_cols = ['test', 'Cond']
(
    df1
    .set_index(index_cols)
    .combine_first(
        df2.set_index(index_cols)
    ).reset_index()
)

说明:

  • set_index将指定的列移动到索引中,表示每一行都应该由其testCond列标识
  • foo.combine_first(bar)将标识foobar之间匹配的索引+列标签,并在foo为NaN或缺少列/行的地方填充bar中的值。在这种情况下,由于set_index,两个数据帧的行将匹配,其中testCond是相同的,然后df2中的ULLL值将填充到输出的相应列中
  • reset_index简单地反转set_index调用,以便testCond再次成为正则列

请注意,此操作可能会破坏列的顺序,因此,如果这对您很重要,那么您可以在最后调用.reindex(df1.columns, axis=1),这将按df1中的原始顺序重新排列列

方法2:merge

或者,您可以使用merge方法,该方法允许您在不使用set_index的情况下直接对列进行操作,但需要一些其他预处理:

index_cols = ['test', 'Cond']
(
    df1
    .drop(['LL', 'UL'], axis=1)
    .merge(
       df2,
       on=index_cols
    )
)

.drop调用是必需的,因为否则merge将在输出中包括来自两个数据帧的ULLL列:

  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

使用哪个

对于您提供的数据,merge似乎是更自然的操作-如果您从不期望UL和LL在df1中有任何数据,那么如果可能的话,我建议只从输入CSV中完全删除这些列标题,这样df1就根本没有这些列。在这种情况下,drop调用将不再是必需的,并且所需的merge调用非常有表现力

但是,如果您期望df1有时会有ULLL的实际值,并且希望在输出中包含这些值,那么combine_first解决方案就是您想要的。请注意,如果df1df2对于特定行/列具有不同的非空值,则df1.combine_first(df2)将从df1中选择值并忽略df2值。如果您想对来自df2的值进行优先级排序,那么您想反过来调用它,即df2.combine_first(df1)

相关问题 更多 >