【问题标题】:Is there a pythonic way to inter over two dataframes and compare their rows?有没有一种 Python 的方式来交互两个数据帧并比较它们的行?
【发布时间】:2019-11-21 17:20:54
【问题描述】:

鉴于以下两个数据框:

df1 # 从 excel 电子表格中读取

data1 = {'ID':['1','2'],
         'Prod Family Desc':['Install','Maintenance'], 'Prod Family Code':['',''], 
         'Prod Type Desc':['Installation Serice','Maintenance Service'],'Prod Type Code':['',''],
        } 
df1 = pd.DataFrame(data1) 
print(df1)

结果 df1:

  ID Prod Family Desc Prod Family Code       Prod Type Desc Prod Type Code
0  1          Install                   Installation Serice
1  2      Maintenance                   Maintenance Service

df2 #是SQL查询的结果

data2 = {'Prod Class':['F','F','T','T'],
        'Prod Desc':['Install','Maintenance','Installation Serice','Maintenance Service'],'Prod Code':['2525','2534','H123','H321']
        }

df2 = pd.DataFrame(data2) 
print(df2)

结果 df2:

  Prod Class            Prod Desc Prod Code
0          F              Install      2525
1          F          Maintenance      2534
2          T  Installation Serice      H123
3          T  Maintenance Service      H321

从 df2 分配 Prod Family CodeProd Type Code 的最佳方法是什么到 Prod Family CodeProd Type Code on df1?

我正在这样做:

stype = df2.loc[df2['Prod Class'] == "T"] 

family = df2.loc[df2['Prod Class'] == "F"]

for i, concaterow in df1.iterrows():
    for j, styp in stype.iterrows():

        if (concaterow['Prod Type Desc'] == styp['Prod Desc']):
            df1.loc[i,'Prod Type Code'] = styp['Prod Code']

    for j, scat in family.iterrows():
        if (concaterow['Prod Family Desc'] == scat['Prod Desc']):
            df1.loc[i,'Prod Family Code'] = scat['Prod Code']

print(df1)

结果如预期:

  ID Prod Family Desc Prod Family Code       Prod Type Desc Prod Type Code
0  1          Install             2525  Installation Serice           H123
1  2      Maintenance             2534  Maintenance Service           H321

这种操作有pythonic的方式吗?

#

**编辑@FatihAkici 问题的答案。

@FatihAkici - 由于 df2 是 SQL 查询的结果,我的预期结果是插入表中的最新值。因此,给定 df2 如下:

data2 = {'Prod Class':['F','F','F','T','T'], 'Prod Desc':['Install','Maintenance','Install','Installation Serice','Maintenance Service'],'Prod Code':['2525','2534','2536','H123','H321'] } ```

The expected result would be: 
```ID Prod Family Desc Prod Family Code Prod Type Desc Prod Type Code 
 0 1  Install          2536             Installation Serice H123 
 1 2 Maintenance       2534             Maintenance Service H321 

【问题讨论】:

  • 您通常不想迭代数据帧,而是想以某种方式加入它们。查看pandas.pydata.org/pandas-docs/stable/user_guide/merging.html
  • 如果您的 df2 中有重复项,您的预期输出是什么,例如 'Prod Desc':['Install', 'Maintenance', 'Install', 'Installation Serice', 'Maintenance Service']'Prod Code':['1','2','3','4', '5']
  • 您可以将此添加到您的帖子中吗?我看不懂。
  • 等待您正确格式化您的答案,以便我可以帮助您。
  • @FatihAkici 格式答案已添加到帖子中。谢谢。

标签: python pandas dataframe


【解决方案1】:

你可以结合pd.DataFrame.assignpd.DataFrame.merge

df1.assign(**{
    "Prod Family Code" : df1.merge(df2, left_on = "Prod Family Desc", right_on = "Prod Desc")["Prod Code"],
    "Prod Type Code"   : df1.merge(df2, left_on = "Prod Type Desc", right_on = "Prod Desc")["Prod Code"]})

在您的示例中,您的数据框 df1 包含 2 个空列 Prod Family CodeProd Type Code 接收结果,但这不是此方法的要求

【讨论】:

  • 感谢您抽出宝贵时间帮助我。您发布的代码是否假设更改原始 df1?当我运行此代码并且他们打印 df1 时,没有任何变化。我可以错过什么吗?
  • 欢迎您。不应该更改 df1。为此,只需添加df1 = df1.assign(..)
  • 当我在 df2 上没有重复描述时,此解决方案有效,我在 df2 中有重复描述的情况下进行了测试(请参阅帖子中编辑的 df2),并用它覆盖维护产品代码第二个安装产品代码。我将尝试对您的代码进行一些调整以尝试解决该问题。
  • 如果想保留df1的行数,每次合并加how='left'即可
【解决方案2】:

我相信合并可以完成你正在寻找的东西

df1.merge(df2, how='left', left_on=['Prod Family Desc'], right_on=['Prod Desc'])

【讨论】:

  • 感谢您的建议。当我运行合并时,df1 不会随着产品代码的值而改变。另外,在将值分配给 Prod Code 时,我需要考虑 Prod Class,因为数据库可以对 Family 和 Type 进行相同的描述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
  • 2011-07-21
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
  • 1970-01-01
  • 2018-10-30
相关资源
最近更新 更多