尝试合并2个数据帧但得到ValueError

时间:2018-06-01 19:20:07

标签: python pandas dataframe

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

> 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参数有关。但我不知道如何解决它而不必保存它,它并不重要,但是我必须这样做是一种烦恼。

7 个答案:

答案 0 :(得分:39)

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

答案 1 :(得分:37)

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

答案 2 :(得分:2)

@Arnon Rotem-Gal-Oz的答案大部分是正确的。但我想指出df['year']=df['year'].astype(int)df.year.astype(int)之间的区别。 df.year.astype(int)返回数据框的视图,并且没有明确更改类型,至少在熊猫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

杂草对象, 数量对象

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

merged = df.merge[df1, on="something"]

答案 6 :(得分:0)

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

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

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