我们如何结合多个数据帧使用合并。
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中选择值。
有可能..请提出任何建议帮助我...
答案 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
.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
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
我敢肯定有更好的方法可以做到这一点,但是我希望这会有所帮助!