当前位置: 首页 > 知识库问答 >
问题:

基于另一个数据帧的公共列筛选和替换一个数据帧中的值

太叔乐家
2023-03-14

我有一个关于熊猫以及正确索引和替换值的问题。

我有两个数据帧,df1和df2,具有相同的列(Col1、Col2、Col3和Col4)。

df1 = pd.DataFrame([['A','b','x',1], ['A','b','y',2], ['A','c','z',3], ['B','b','x',4]], columns=['Col1', 'Col2', 'Col3', 'Col4'])
df2 = pd.DataFrame([['A','b','y',0], ['B','b','x',0]], columns=['Col1','Col2','Col3','Col4'])
    
df1
  Col1 Col2 Col3 Col4
0    A    b    x    1
1    A    b    y    2
2    A    c    z    3
3    B    b    x    4
    
df2
  Col1 Col2 Col3 Col4
0    A    b    y    0
1    B    b    x    0

在df1中,我想用另一个值(比如100)替换与df2中其他列(Col1、Col2和Col3)的值匹配的行中Col4中的值。

生成的df1看起来像这样:

df1
  Col1 Col2 Col3 Col4
0    A    b    x    1
1    A    b    y  100
2    A    c    z    3
3    B    b    x  100

我试过这样的方法:

columns = list(df1.columns)    
columns.remove('Col4')
df1.loc[(df1[cols] == df2[cols].values).all(axis=1)]['Col4']=100

但是我得到了错误,我不确定这是否达到了我想要的。

共有3个答案

卢俭
2023-03-14

你可以试试这个:

new_df =df1.merge(df2, on=['Col1', 'Col2', 'Col3'], how='left', suffixes=(None, '_y'))
new_df.loc[new_df.Col4_y.notna(), 'Col4'] = 100

new_df.loc[:, df1.columns]


   Col1 Col2    Col3    Col4
0   A    b        x       1
1   A    b        y      100
2   A    c        z       3
3   B    b        x      100

我还想指出的性能的方法与合并和与isin

%%timeit
# best answer
cols = ['Col1', 'Col2', 'Col3']

temp1 = df1.set_index(cols)

temp2 = df2.set_index(cols)

# get the booleans here 
booleans = temp1.index.isin(temp2.index)


# this assigns 100 to only rows in Col4
# that are True
df1.loc[booleans, 'Col4'] = 100

3.97 ms ± 765 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
cols = ['Col1', 'Col2', 'Col3']
(df1.merge(df2, 
           on = cols, 
           how = 'left', 
           indicator=True, 
           suffixes = (None, '_y'))
    .assign(Col4 = lambda df: np.where(df._merge == 'both', 
                                       100, 
                                       df.Col4))
   .loc[:, df1.columns]
)
5.78 ms ± 660 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%time
# by kelvt
df1 = df1.set_index(['Col1', 'Col2', 'Col3'])
_df2 = df2.set_index(['Col1', 'Col2', 'Col3'])

# set arbitrary value for Col4
_df2['Col4'] = 100

# update values in df1
df1.update(_df2)

# reset index
df1 = df1.reset_index()
21.46 ms ± 609 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%%timeit
# my answer
new_df =df1.merge(df2, on=['Col1', 'Col2', 'Col3'], how='left', suffixes=(None, '_y'))
new_df.loc[new_df.Col4_y.notna(), 'Col4'] = 100
1.49 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

如果你的df1和df2足够大,这很重要

童子明
2023-03-14

让我们使用熊猫。数据帧。更新方法:

df1 = df1.set_index(['Col1', 'Col2', 'Col3'])
_df2 = df2.set_index(['Col1', 'Col2', 'Col3'])

# set arbitrary value for Col4
_df2['Col4'] = 100

# update values in df1
df1.update(_df2)

# reset index
df1 = df1.reset_index()

杜俊远
2023-03-14

您可以使用索引执行isin,并通过布尔屏蔽分配值:


cols = ['Col1', 'Col2', 'Col3']

temp1 = df1.set_index(cols)

temp2 = df2.set_index(cols)

# get the booleans here 
booleans = temp1.index.isin(temp2.index)


# this assigns 100 to only rows in Col4
# that are True
df1.loc[booleans, 'Col4'] = 100

df1

  Col1 Col2 Col3  Col4
0    A    b    x     1
1    A    b    y   100
2    A    c    z     3
3    B    b    x   100

或者,您可以使用pd解决它。合并指示器参数:

(df1.merge(df2, 
           on = cols, 
           how = 'left', 
           indicator=True, 
           suffixes = (None, '_y'))
    .assign(Col4 = lambda df: np.where(df._merge == 'both', 
                                       100, 
                                       df.Col4))
   .loc[:, df1.columns]
)

  Col1 Col2 Col3  Col4
0    A    b    x     1
1    A    b    y   100
2    A    c    z     3
3    B    b    x   100
 类似资料:
  • 我有两个数据帧df1和df2 df1如下 df2就像 我想根据df2中与df1中的列名匹配的单元格值将值从df1复制到df2,所以我的df3应该看起来像 df3 基本上,我想根据df2的单元格值(df1中的列名)从df1复制df2中的列 如果它仍然令人困惑,请告诉我

  • 我有两个数据帧df1和df2。df1就像一个具有以下值的字典 df2具有以下值: 我想基于df1数据帧中的,将df2拆分为3个新的数据帧。 日期,TLRA_权益栏应位于数据框 预期产出: > 数据帧 消费者,非周期性数据帧 请让我知道如何有效地做。我想做的是连接列名,例如,然后根据列名的前半部分分割数据帧。 代码: 但这很复杂。需要更好的解决方案。

  • 我有两个数据帧。我需要用第二列中的平均值更新第一列中的一列,并按索引分组。这里是示例df1(col1是索引) df2(col1是索引) 我需要df2的col2(a=2,d=3)的平均值,并且只更新col3=X的行的df1 我试过这个 只有在我不使用loc的情况下,它才有效。 我试图得到的结果是df1(col1是索引)

  • 我和Spark一起在Databricks上工作。编程语言是Scala。 我有两个数据帧: 主数据框:见截图:1 查找数据帧:参见屏幕截图3 我想: 查找主数据框中“年龄”=-1的所有行 我对如何做这件事伤了脑筋。我唯一想到的是将dataframe存储为DataRicks中的表,并使用SQL语句(SQL.Context.SQL…),结果非常复杂。 我想知道是否有更有效的方法。 编辑:添加可复制的示例

  • 情况: 两个数据帧(df1和df2)具有相同的三个索引,例如“A”、“B”、“C”。df1和df2的列数不同。df1和df2中的所有单元格都填充了float类型的数据。 DF1: DF2: 目标: 从df2中选择的列(例如“BBB”)与df1的每列相加后,结果应存储在新的数据帧(df_new)中。df_new的格式应为df1(列数和行数),并具有与df1相同的列名和索引。 new_df: 我的做法

  • 用其他dataframe的列值替换dataframe的一列中的nan值时出现问题。下面是一个测试示例: 我想用其他dataframe中的特定值替换列名中的Nan值(如果其中有一些Nan值,则不是其他列),例如此dataframe中的Name2值: 我想得到的是: 这是此示例的测试代码: 然后我尝试了这三种方法,但都不起作用——我的数据帧始终保持Nan值。 你能告诉我哪里出错了吗?