如何使用多个数据帧的合并。
columns_List = Emp_Id, Emp_Name, Dept_Id...
我在python脚本中使用了两个数据框架。df1[Columns_List],df2[columns_List].在这两个数据文件中,我都使用了相同的列,但在这两个数据格式中,我的值将不同。
我如何使用合并,这样就可以说:在Dataframe df1[Columns_List]中--我有Emp_Name null,然后我想从df2[Columns_list]中选择Emp_Name。
我正在尝试创建一个输出CSV文件。
如果我的问题是错误的,请原谅。
请查找下面的样本数据。
给Dataframe1 -- df1Columns_List ..。请查找以下输出
EmpID,Emp_Name,Dept_id,DeptName
1,,1,
2,,2,给Dataframe2 -- df2Columns_List ..。请查找以下输出
EmpID,Emp_Name,Dept_id,DeptName
1,XXXXX,1,Sciece
2,YYYYY,2,Maths我有消息来源作为Json文件。一旦我通过python解析了数据,我就会在同一个脚本中使用2个dataframes。在数据帧1( df1)中,我使用Emp_Name & Dept_Name作为null。在这种情况下,我想从Dataframe2 (df2)中选择数据。
在上面的例子中,我提供了几个列。但我可能有很多列。但是列的顺序和列名总是一样的。我试图以这样的方式实现,如果来自df1的任何列为null,那么我想从df2中选择值。
这有可能吗..。请帮我解决任何建议..。
发布于 2019-06-30 15:17:51
您可以使用pandas.DataFrame.combine。该方法可以满足您的需要:它根据一个自定义函数从两个数据文件中提取元素,构建一个dataframe。
然后,您可以编写一个自定义函数,它从dataframe 1中选择元素,除非该值为null,在这种情况下,元素从dataframe 2中提取。
考虑以下两种数据格式。我根据您的示例构建了它们,但是有一个小的区别,强调只有emtpy字符串才会被替换:
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)]))虽然有点紧凑,但是没有什么比一些基本的python技术,比如列表理解,加上pandas.DataFrame.combine的使用更简单了。熊猫的方法在我上面链接的文档中有详细的描述。它逐列比较两个dataframes :这些列被传递给一个必须返回pandas.Series的自定义函数。本系列将成为返回的dataframe中的列。
在这种情况下,自定义函数是一个lambda,它使用列表理解来循环遍历元素对(每个列一个),并且只选择对中的一个元素(第一个元素(如果不是null ),否则是第二个元素)。
发布于 2019-06-30 15:46:37
您可以使用掩码获取空值并替换这些值。最棒的部分是,你不需要看任何东西,这个功能会找到替代你的东西。
您还可以调整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发布于 2019-06-30 15:24:39
我复制了你的数据文件:
# 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我相信有更好的方法来做这件事,但我希望这会有帮助!
https://stackoverflow.com/questions/56825147
复制相似问题