尝试合并2个数据框但出现ValueError


79

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

> 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参数有关。但是我不知道有没有保存就修复它的想法,这没什么大不了,但是我不得不这么做。


当我使用联接而不是合并时,出现了相同的错误。
调制解调器Rakesh

Answers:


112

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

编辑:还请注意Anderson Zhu的评论:万一您None在一个数据框中有或缺少值,则需要使用Int64而不是int。请参阅此处的参考。


谢谢它的工作。自从我每年保存为整数以来,Kinda很奇怪。
PEREZje

13
为什么不df.year.astype(int)呢?
rafaelc

我最终确实以另一种方式修复了该问题,只是将所有年份变量保存为整数形式的数据框。从来没有想过它们是字符串。
PEREZje

@RafaelC可能更好
Arnon Rotem-Gal-Oz

2
万一您在一个数据帧中没有值或缺少值,则需要使用Int64代替int。请参阅此处的参考。

37

我发现我的dfs都具有相同的类型列(str),但是从切换joinmerge解决了该问题。


5
同样在这里。如果有人知道为什么,请在下面写下:)
raummensch

相同。确实很奇怪,我唯一的猜测就是,即使一切都是type object,在进行联接时,pandas会再次尝试隐式评估数据类型……但是merge也为我解决了。
15Step

5
@raummensch和@ 15Step,我遇到了同样的问题。@MatthiasFripp的答案是:link,它可以对字符串进行合并但不能进行合并的原因。基本上df1.join(df2)总是通过索引进行合并,df2而索引df1.merge(df2)将在列上合并。所以基本上,我们试图以掀起了字符串和一个整数合并,尽管两列分别为字符串..
力高

3

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

示例:在表1中,日期作为字符串,而在表2中,日期作为日期时间。因此,在合并之前,我们需要将日期更改为通用数据类型。


2

@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

杂草对象,数量对象


1

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


0

这个简单的解决方案对我有用

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

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


0

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

df["something"] = df["something"].astype(int)

merged = df.merge[df1, on="something"]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.