在python中合并两个数据帧的替代方法

在python中合并两个数据帧的替代方法,python,pandas,dataframe,merge,Python,Pandas,Dataframe,Merge,让我们举一个简单的例子。我有第一个数据帧: df = pd.DataFrame(dict(Name=['abc','def','ghi'],NoMatter=['X','X','X'])) df Name NoMatter 0 abc X 1 def X 2 ghi X 出于某些原因,我想使用一个For循环,它向df添加一个列值,并从每次迭代中更改的另一个数据帧进行一些处理: # strucutre of for loop I would l

让我们举一个简单的例子。我有第一个数据帧:

df = pd.DataFrame(dict(Name=['abc','def','ghi'],NoMatter=['X','X','X']))
df
  Name NoMatter
0  abc        X
1  def        X
2  ghi        X
出于某些原因,我想使用一个For循环,它向df添加一个列值,并从每次迭代中更改的另一个数据帧进行一些处理:

# strucutre of for loop I would like to use :
for i in range(something) :
    add the column Value to df from df_value
    other treatment not usefull here

# appearance of df_value (which change at each iteration of the for loop) :
  Name  Value
0  abc      1
1  def      2
2  ghi      3
# similar to Excel vlookup function
def vlookup(df,ref,col_ref,col_goal):
    return pd.DataFrame(df[df.apply(lambda x: ref == x[col_ref],axis=1)][col_goal]).iloc[0,0]

df['Value'] = df['Name'].apply(lambda x : vlookup(df_value,x,'Name','Value'))

#Output : 

  Name NoMatter  Value
0  abc        X      1
1  def        X      2
2  ghi        X      3

但是,我不希望使用合并,因为这需要在添加当前迭代的列值之前删除在上一次迭代中添加的列值。是否有一种方法可以将Value列添加到df中,只需以如下方式开始赋值:

df['Value'] = XXX
预期产出:

  Name NoMatter  Value
0  abc        X      1
1  def        X      2
2  ghi        X      3
[编辑]

我不想使用合并,因为在for循环的第四次迭代中,df将有以下列:

名称NoMatter Value1 Value2 Value3 Value4

而我只想:

名称NoMatter值4


我每次都可以删除上一列,但似乎效率不高。这就是为什么我只是在寻找一种为Value列赋值的方法,而不是添加列。类似于Excel中的vlookup函数,从df_值数据应用于df。

3种连接数据帧的方法

追加(df2)#将df1中的行添加到df2的末尾(列应相同)

pd.concat([df1,df2],axis=1)#将df1中的列添加到df2的末尾(行应相同)

join(df2,on=col1,how='internal')#SQL风格将df1中的列与
df2,其中col的行具有相同的值。怎么可能是“左”、“右”中的一个呢?

以下是解决您问题的方法

import pandas as pd
df = pd.DataFrame(dict(Name=['abc','def','ghi'],NoMatter=['X','X','X']))
df1 = pd.DataFrame(dict(Name=['abc','def','ghi'],Value=[1,2,3]))
new_df=pd.merge(df, df1, on='Name')
new_df
正确的方法是,因为在数据帧上迭代具有糟糕的性能。如果您真的必须这样做,可以寻址单个单元格,但不要假装我建议您这样做:

df = pd.DataFrame(dict(Name=['abc','def','ghi'],NoMatter=['X','X','X']))
df1 = pd.DataFrame(dict(Name=['abc','def','ghi'],Value=[1,2,3]))
df['Value'] = 0    # initialize a new column of integers (hence the 0)
ix = df.columns.get_loc('Value')
for i in range(len(df)):                    # perf is terrible!
    df.iloc[i, ix] = df1['Value'][i]

在看到示例代码之后,如果无法避免循环,我认为这是一种不太糟糕的方法:

newcol = np.zeros(something, dtype='int')  # set the correct type
for i in range(something):
    #compute a value
    newcol[i] = value_for_i_iteration
df['Value'] = newcol                       # assign the array to the new column

也许不是最好的方法,但此解决方案有效,并在每次迭代时替换值列(无需在每次新迭代前删除值列):


你的预期产出是多少?不清楚。我编辑过,谢谢你的帮助comment@SergeBallesta,我只想将Value列添加到df中,而不做任何其他处理(我在文章中谈到了一些处理方法,以证明使用for循环的合理性)。谢谢你的帮助这能回答你的问题吗?如果您只想合并特定列,请执行
df2=pd.merge(df[['Name','Value']],df1,how='left',on='Name'])
感谢您的帮助,但在所有这些情况下,我需要在每次迭代中删除上一个值列感谢您的帮助,但使用合并,我需要在每次迭代中删除上一个值列我不理解您在每次迭代中删除上一个值列的意思。在下一次迭代之前,你能把你面临的问题告诉我吗?
del df['Value']
del列在循环的末尾。这是我在帖子中建议的方式,但我正在寻找一种更有效的方式。Merge-then-delete并不是很有效,所以有一种方法可以通过if语句来实现它。如果此列已读过,请将其替换为新列