我们如何使用pandas在python中将Coalesce用于多个数据帧

时间:2019-06-30 13:20:03

标签: python json pandas dataframe

我们如何结合多个数据帧使用合并。

columns_List = Emp_Id, Emp_Name, Dept_Id...

我在python脚本中使用了两个数据框。 df1[Columns_List]df2[columns_List]。在两个数据帧中,我使用相同的列,但在两个数据帧中,我将具有不同的值。

我如何使用Coalesce,这样说:在数据框df1[Columns_List]中-我有Emp_Name null,然后我想从Emp_Name中选择df2[Columns_list]

我正在尝试创建输出CSV文件。

如果我提出的问题有误,请对不起。

请在下面找到示例数据。

对于Dataframe1-df1 [Columns_List] ..请在下面的输出中找到

EmpID,Emp_Name,Dept_id,DeptName
1,,1,
2,,2,

对于Dataframe2-df2 [Columns_List] ..请在下面的输出中找到

EmpID,Emp_Name,Dept_id,DeptName
1,XXXXX,1,Sciece
2,YYYYY,2,Maths

我有来源作为Json文件。一旦我通过python解析了数据,我就在同一脚本中使用2个数据帧。在数据帧1(df1)中,Emp_Name和Dept_Name为空。在那种情况下,我想从Dataframe2(df2)中选取数据。

在上面的示例中,我提供了几列。但是我可能有n列。但是列顺序和列名称将始终相同。我试图以这种方式实现,如果df1中的任何列为空,那么我想从df2中选择值。

有可能..请提出任何建议帮助我...

3 个答案:

答案 0 :(得分:2)

您可以使用pandas.DataFrame.combine。此方法满足您的需要:根据自定义函数构建一个从两个数据框中获取元素的数据框。
然后,您可以编写一个自定义函数,该函数将从数据帧1中选取元素,除非该元素为null,在这种情况下,该元素将从数据帧2中选取。

请考虑以下两个数据框。我根据您的示例构建了它们,但有一点点不同,即只替换了空字符串:

columnlist = ["EmpID", "Emp_Name", "Dept_id", "DeptName"]

df1 = pd.DataFrame([[1, None, 1, np.NaN], [2, np.NaN, 2, None]], columns=columnlist)
df2 = pd.DataFrame([[1, "XXX", 2, "Science"], [2, "YYY", 3, "Math"]], columns=columnlist)

它们是:

df1
   EmpID  Emp_Name  Dept_id  DeptName
0      1       NaN        1       NaN
1      2       NaN        2       NaN

df2
   EmpID Emp_Name  Dept_id DeptName
0      1      XXX        1  Science
1      2      YYY        3     Math

您需要做的是:

ddf = df1.combine(df2, lambda ss, rep_ss : pd.Series([r if pd.isna(x) else x for x, r in zip(ss, rep_ss)]))

获得ddf

ddf
   EmpID Emp_Name  Dept_id DeptName
0      1      XXX        1  Science
1      2      YYY        2     Math

如您所见,只有df1中的Null值已替换为df2中的相应值。

编辑:更深入的解释

自从我被问到评论以来,让我对解决方案进行更多解释:

ddf = df1.combine(df2, lambda ss, rep_ss : pd.Series([r if pd.isna(x) else x for x, r in zip(ss, rep_ss)]))

虽然有点紧凑,但是除了列表推导和pandas.DataFrame.combine的使用之外,没有什么比其他一些基本的Python技术要多的了。我在上面链接的文档中详细介绍了pandas方法。它逐列比较两个数据帧:将这些列传递给自定义函数,该函数必须返回pandas.Series。该系列成为返回的数据框中的列。
在这种情况下,自定义函数是lambda,它使用列表推导来循环成对的元素对(每列一个),并仅选择该对元素中的一个(第一个(如果不为null,则为null),否则为第二)。

答案 1 :(得分:2)

您可以使用掩码获取空值并将其替换。最好的部分是,您不必费劲。该功能将为您找到要替换的东西。

您还可以调整pd.DataFrame.select_dtypes()函数以适合您的需求,或者仅使用适当的转换和检测措施来检查多个dtype。

import pandas as pd

ddict1 = {
    'EmpID':[1,2],
    'Emp_Name':['',''],
    'Dept_id':[1,2],
    'DeptName':['',''],
}

ddict2 = {
    'EmpID':[1,2],
    'Emp_Name':['XXXXX','YYYYY'],
    'Dept_id':[1,2],
    'DeptName':['Sciece','Maths'],
}

df1 = pd.DataFrame(ddict1)
df2 = pd.DataFrame(ddict2)


def replace_df_values(df_A, df_B):
    ## Select object dtypes
    for i in df_A.select_dtypes(include=['object']):
        ### Check to see if column contains missing value
        if len(df_A[df_A[i].str.contains('')]) > 0:
            ### Create mask for zero-length values (or null, your choice)
            mask = df_A[i] == ''
            ### Replace on 1-for-1 basis using .loc[]
            df_A.loc[mask, i] = df_B.loc[mask, i]

### Pass dataframes in reverse order to cover both scenarios
replace_df_values(df1, df2)
replace_df_values(df2, df1)

df1的初始值:

   EmpID Emp_Name  Dept_id DeptName
0      1                 1         
1      2                 2         

运行功能后df1的输出:

   EmpID Emp_Name  Dept_id DeptName
0      1    XXXXX        1   Sciece
1      2    YYYYY        2    Maths

答案 2 :(得分:1)

我复制了您的数据框:

# df1
    EmpID   Emp_Name    Dept_id DeptName
0   1       1   
1   2       2   

# df2
    EmpID   Emp_Name    Dept_id DeptName
0   1   XXXXX   1   Sciece
1   2   YYYYY   2   Maths
  1. 如果要将df1.column中的缺失值(NaN)替换为df2.column中的现有值,则可以使用.fillna()。例如:
df1['Emp_Name'].fillna(df2['Emp_Name'], inplace=True)

# df1

    EmpID   Emp_Name    Dept_id DeptName
0   1   XXXXX   1   
1   2   YYYYY   2   

  1. 如果要将给定列中的所有值替换为另一个数据框的同一列中的值,则可以使用列表推导。
df1['DeptName'] = [ each for each in list(df2['DeptName'])]

    EmpID   Emp_Name    Dept_id DeptName
0   1   XXXXX   1   Sciece
1   2   YYYYY   2   Maths

我敢肯定有更好的方法可以做到这一点,但是我希望这会有所帮助!