【问题标题】:Trying to merge 2 dataframes but get ValueError尝试合并 2 个数据帧但得到 ValueError
【发布时间】:2018-11-11 23:24:18
【问题描述】:

这是我保存在两个变量中的两个数据框:

> print(df.head())
>
          club_name  tr_jan  tr_dec  year
    0  ADO Den Haag    1368    1422  2010
    1  ADO Den Haag    1455    1477  2011
    2  ADO Den Haag    1461    1443  2012
    3  ADO Den Haag    1437    1383  2013
    4  ADO Den Haag    1386    1422  2014
> print(rankingdf.head())
>
           club_name  ranking  year
    0    ADO Den Haag    12    2010
    1    ADO Den Haag    13    2011
    2    ADO Den Haag    11    2012
    3    ADO Den Haag    14    2013
    4    ADO Den Haag    17    2014

我正在尝试使用以下代码合并这两个:

new_df = df.merge(ranking_df, on=['club_name', 'year'], how='left')

添加 how='left' 是因为我的ranking_df 中的数据点少于标准df 中的数据点。

预期的行为是这样的:

> print(new_df.head()) 
> 

      club_name  tr_jan  tr_dec  year    ranking
0  ADO Den Haag    1368    1422  2010    12
1  ADO Den Haag    1455    1477  2011    13
2  ADO Den Haag    1461    1443  2012    11
3  ADO Den Haag    1437    1383  2013    14
4  ADO Den Haag    1386    1422  2014    17

但我收到此错误:

ValueError:您正在尝试合并 object 和 int64 列。如果 你想继续你应该使用 pd.concat

但我不想使用 concat,因为我想合并树而不仅仅是添加它们。

另一个在我看来很奇怪的行为是,如果我将第一个 df 保存到 .csv 然后将该 .csv 加载到数据框中,我的代码就可以工作。

代码:

df = pd.DataFrame(data_points, columns=['club_name', 'tr_jan', 'tr_dec', 'year'])
df.to_csv('preliminary.csv')

df = pd.read_csv('preliminary.csv', index_col=0)

ranking_df = pd.DataFrame(rankings, columns=['club_name', 'ranking', 'year'])

new_df = df.merge(ranking_df, on=['club_name', 'year'], how='left')

我认为它与 index_col=0 参数有关。但是我不知道要修复它而不必保存它,这并不重要,但我必须这样做是一种烦恼。

【问题讨论】:

  • 当我使用join而不是merge时遇到同样的错误。

标签: python pandas dataframe


【解决方案1】:

在您的一个数据框中,年份是一个字符串,另一个是 int64 您可以先转换它然后加入(例如df['year']=df['year'].astype(int) 或 RafaelC 建议的df.year.astype(int)

编辑:还要注意 Anderson Zhu 的评论:以防万一您的数据框中有 None 或缺失值,您需要使用 Int64 而不是 int。请参阅参考资料here

【讨论】:

  • 感谢它的工作。有点奇怪,因为我每年都保存为整数。
  • 为什么不df.year.astype(int)
  • 我最终以另一种方式修复了它,只是将所有年份变量作为整数保存到数据框中。从来没想过它们是字符串。
  • @RafaelC 这可能更好
  • 以防万一您的数据框中有 None 或缺失值,您需要使用 Int64 而不是 int。请参阅参考资料here
【解决方案2】:

我发现我的 dfs 都有相同的类型列 (str),但从 join 切换到 merge 解决了这个问题。

【讨论】:

  • 这里也一样。如果有人知道为什么,请写在下面:)
  • 相同。确实很奇怪,我唯一的猜测是,即使所有内容都是 object 类型,在进行 join 时,pandas 也会尝试再次隐式评估数据类型......但合并也为我解决了这个问题。
  • @raummensch 和@15Step,我遇到了同样的问题。在@MatthiasFripp 的答案中可以找到合并对字符串有效但无法加入的原因:link。基本上df1.join(df2) 总是通过df2 的索引合并,而df1.merge(df2) 将在列上合并。所以基本上我们试图基于一个字符串和一个整数进行合并,即使两列都是字符串..
  • 这也发生在我身上。感谢您告诉我们。
  • 每 6 个月我会在忘记这个技巧后找到回到这个答案的方法,哈哈,谢谢 Alex!
【解决方案3】:

@Arnon Rotem-Gal-Oz 的答案在很大程度上是正确的。但我想指出df['year']=df['year'].astype(int)df.year.astype(int) 之间的区别。 df.year.astype(int) 返回数据框的视图并且不会显式更改类型,至少在 pandas 0.24.2 中。 df['year']=df['year'].astype(int) 显式更改类型,因为它是一个赋值。我认为这是永久更改列的 dtype 的最安全方法。

例子:

df = pd.DataFrame({'Weed': ['green crack', 'northern lights', 'girl scout cookies'], 'Qty':[10,15,3]}) df.dtypes

杂草对象, 数量 int64

df['Qty'].astype(str) df.dtypes

杂草对象, 数量 int64

即使将 inplace arg 设置为 True 有时也无济于事。我不知道这是为什么 虽然发生。在大多数情况下,inplace=True 等于显式赋值。

df['Qty'].astype(str, inplace = True) df.dtypes

杂草对象, 数量 int64

现在是任务,

df['Qty'] = df['Qty'].astype(str) df.dtypes

杂草对象, 数量对象

【讨论】:

  • pandas 1.2.4 开始,Series.astype 没有inplace 参数。它有一个copy 参数,它的行为方式可能相同,但我没有测试过。
【解决方案4】:

当两个表中的公共列具有不同的数据类型时会发生这种情况。

示例:在 table1 中,您将 date 作为字符串,而在 table2 中,您将 date 作为日期时间。所以在合并之前,我们需要把date改成普通的数据类型。

【讨论】:

    【解决方案5】:

    附加:当您将 df 保存为 .csv 格式时,日期时间(在此特定情况下为年份)保存为对象,因此您需要在进行合并时将其转换为整数(在此特定情况下为年份)。这就是为什么当您从 csv 文件上传两个 df 时,您可以轻松地进行合并,而如果一个 df 是从 csv 文件上传而另一个是从现有 df 上传,则会出现上述错误。这有点烦人,但如果牢记,有一个简单的解决方案。

    【讨论】:

      【解决方案6】:

      首先检查要合并的列的类型。你会看到其中一个是字符串,另一个是int。然后将其转换为 int 如下代码:

      df["something"] = df["something"].astype(int)
      
      merged = df.merge[df1, on="something"]
      

      【讨论】:

        【解决方案7】:

        这个简单的解决方案适合我

            final = pd.concat([df, rankingdf], axis=1, sort=False)
        

        但您可能需要先删除一些重复的列。

        【讨论】:

          【解决方案8】:

          在我的情况下,发生这种情况是因为我试图合并不是索引的列,所以为了解决这个问题,我使用了我在文档中找到的这段代码:

          df.set_index('key').join(other.set_index('key'))
          

          文档: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.join.html set key to be the index

          【讨论】:

            猜你喜欢
            • 2020-07-05
            • 2021-10-27
            • 1970-01-01
            • 2023-04-11
            • 2019-08-11
            • 1970-01-01
            • 1970-01-01
            • 2018-09-07
            • 2022-01-07
            相关资源
            最近更新 更多