Pandas concat 失败

33
我正在尝试将以下两个CSV文件的数据框连接起来:
df_a: https://www.dropbox.com/s/slcu7o7yyottujl/df_current.csv?dl=0

df_b: https://www.dropbox.com/s/laveuldraurdpu1/df_climatology.csv?dl=0

这两个都有相同的列数和列名。然而,当我这样做时:
pandas.concat([df_a, df_b])

我遇到了一个错误:
AssertionError: Number of manager items must equal union of block items
# manager items: 20, # tot_items: 21

怎么修复这个问题?

1
刚刚尝试了您的数据,使用 pandas==0.17.1concat 没有问题。 - Stefan
嗯,不太确定发生了什么事情...我仍然得到错误,我也使用了 pandas == 0.17.1。 - user308827
我正在使用pandas 0.17.1,Python 2.7.11在Ubuntu 14.04上,对我来说它也很好用。 - agold
我检查列名 print df_a.columns == df_b.columns 并输出: [ True True True True True True True True True True True True True True False False True False True False False] - jezrael
感谢@jezrael,列名不是按相同顺序排列的,但它们都存在。 - user308827
4个回答

45

我认为只有满足以下两个条件才会出现此错误:

  1. 数据帧具有不同的列。(即 (df1.columns == df2.columns)False
  2. 列中有重复值。

基本上,如果你用 concat 把具有列名 [A,B,C][B,C,D] 的数据帧连接起来,它会尝试为每个不同的列名生成一个系列。所以,如果我尝试连接第三个数据帧 [B,B,C],它就不知道要添加哪一列,最终得到的列数比它认为需要的少。

如果你的数据帧是这样的 df1.columns == df2.columns,那么无论如何都可以工作。所以你可以连接 [B,B,C][B,B,C],但不能连接到 [C,B,B],因为如果列相同,它可能只使用整数索引或其他什么东西。


我看过的关于这个问题最好的解释。谢谢。 - Jonathan Nappee
我在空间扩展geopandas中遇到了问题,其中.overlay()操作由于与原始帖子非常相似的错误而失败。如果两个地理数据框具有相同的列名,则它们将仅在输出数据框中枚举一次。在第三个叠加操作中,它将抛出此错误。因此,如果您正在进行链式叠加,请确保链中每个地理数据框的列名不同。 - wfgeo
谢谢!FYI查找重复列: duplicates = df.columns.duplicated(keep=False) [x[0] for x in tuple(zip(df.columns, duplicates)) if x[1]] - Wouter
重复的列!当然,非常感谢清晰的答案! - FiercestJim

9

这里提供的答案没有解决我的问题,但是这个答案解决了我的问题。

问题所在是一个或两个数据框中存在重复的列。

以下是修复重复列的方法(按照上面的答案):

df = df.loc[:,~df.columns.duplicated()]

6
您可以通过“手动”串联来解决这个问题,在这种情况下,您的
list_of_dfs = [df_a, df_b]

而不是运行
giant_concat_df = pd.concat(list_of_dfs,0)

您可以将所有的数据框转换为字典列表,然后使用chain合并这些列表,再将它们转化为新的数据框。

from itertools import chain
list_of_dicts = [cur_df.T.to_dict().values() for cur_df in list_of_dfs]    
giant_concat_df = pd.DataFrame(list(chain(*list_of_dicts)))

1
请注意,这个解决方案完成所需的时间会显著不同,并且在处理大型数据框时也会消耗大量内存。 - Karatheodory

2

很遗憾,源文件已经不可用,所以我不能在您的情况下检查我的解决方案。在我的情况下,当:

  1. 数据框中有两个同名列(我有一个ID和一个id列,然后我将它们转换为小写,所以它们变成了相同的列)
  2. 同名列的值类型不同

这是一个给出了我所说的错误的示例:

df1 = pd.DataFrame(data=[
    ['a', 'b', 'id', 1],
    ['a', 'b', 'id', 2]
], columns=['A', 'B', 'id', 'id'])

df2 = pd.DataFrame(data=[
    ['b', 'c', 'id', 1],
    ['b', 'c', 'id', 2]
], columns=['B', 'C', 'id', 'id'])
pd.concat([df1, df2])
>>> AssertionError: Number of manager items must equal union of block items
 # manager items: 4, # tot_items: 5

删除/重命名其中一个列可以使该代码正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接