【问题标题】:Pandas concat yields ValueError: Plan shapes are not alignedPandas concat 产生 ValueError:计划形状未对齐
【发布时间】:2014-12-01 07:25:57
【问题描述】:

在 pandas 中,我尝试连接一组数据帧,但出现此错误:

ValueError: Plan shapes are not aligned

我对@9​​87654322@ 的理解是,它会在列相同的地方加入,但对于那些找不到的地方,它将用 NA 填充。这似乎不是这里的情况。

这里是 concat 语句:

dfs = [npo_jun_df, npo_jul_df,npo_may_df,npo_apr_df,npo_feb_df]
alpha = pd.concat(dfs)

【问题讨论】:

  • 您只需要发布一些数据和引发此错误的最小示例。模拟一些您希望看到的输出的奖励积分。
  • 您的列表中有一个尾随逗号:dfs = [npo_jun_df, npo_jul_df,npo_may_df,npo_apr_df,npo_feb_df,<------ ] 删除并重试
  • 实际上,如果您的列表中有一个尾随逗号,它应该仍然有效,即使您的列发生冲突,它也应该仍然有效。您需要发布我们可以用来重现您的错误的数据和代码,注意我运行的是 pandas 版本 0.14.1,您运行的是什么版本的 pandas、numpy 和 python
  • 我最近遇到了同样的错误,原来我在使用追加语句df=df_t.append(df_e) 加入时在数据框df_e 中有重复的列名。在语句正常工作之前,我不小心添加了一个重复的列,它给了他们与上面相同的错误语句。
  • 如果其他人收到此错误(很可能是由于列名重复),请尝试:df.columns.duplicated() 为每个数据框。 pd.concat 无法处理重复的列名。

标签: python pandas concat


【解决方案1】:

我收到了 ValueError:将数据框添加在一起时,计划形状未对齐。我试图循环遍历 Excel 工作表并在清理它们之后将它们连接在一起。

由于它们是多个无列而引发错误,我使用以下代码删除了这些列:

df = df.loc[:, df.columns.notnull()] # 在stackoverflow上找到

【讨论】:

    【解决方案2】:

    错误是有重复列的结果。使用以下函数可以在不影响数据的情况下删除重复函数。

    def duplicated_varnames(df):
        repeat_dict = {}
        var_list = list(df) # list of varnames as strings
        for varname in var_list:
            test_list = [v for v in var_list if v == varname] 
            if len(test_list) > 1: 
                repeat_dict[varname] = len(test_list)
            if len(repeat_dict)>0:
                df = df.loc[:,~df.columns.duplicated()]
        return df
    

    【讨论】:

      【解决方案3】:

      如何从pandas.concat(...)重现上述错误:

      ValueError:计划形状未对齐

      Python (3.6.8) 代码:

      import pandas as pd
      df = pd.DataFrame({"foo": [3] })
      print(df)
      df2 = pd.concat([df, df], axis="columns")
      print(df2)
      df3 = pd.concat([df2, df], sort=False) #ValueError: Plan shapes are not aligned
      

      哪个打印:

         foo
      0    3
      
         foo  foo
      0    3    3
      ValueError: Plan shapes are not aligned
      

      错误说明

      如果第一个 pandas 数据帧(此处为 df2)有一个重复的命名列并被发送到 pd.concat,而第二个数据帧的维度与第一个不同,则会出现此错误。

      解决方案

      确保没有重复的命名列:

      df_onefoo = pd.DataFrame({"foo": [3] })
      print(df_onefoo)
      df_onebar = pd.DataFrame({"bar": [3] })
      print(df_onebar)
      df2 = pd.concat([df_onefoo, df_onebar], axis="columns")
      print(df2)
      df3 = pd.concat([df2, df_onefoo], sort=False)
      print(df2)
      

      打印:

         foo
      0    3
      
         bar
      0    3
      
         foo  bar
      0    3    3
      
         foo  bar
      0    3    3
      

      Pandas concat 对于该错误消息可能会更有帮助。这是一个直接的冒泡实现,它是教科书 python。

      【讨论】:

        【解决方案4】:

        您需要为要连接的所有 df 使用相同的标头名称。

        例如使用:

        标题名称 = 列表(df)

        Data = Data.filter(headername)

        【讨论】:

          【解决方案5】:

          编写了一个小函数来连接重复的列名。 如果原始数据帧未排序,则函数关心排序,输出将是排序的。

          def concat_duplicate_columns(df):
              dupli = {}
              # populate dictionary with column names and count for duplicates 
              for column in df.columns:
                  dupli[column] = dupli[column] + 1 if column in dupli.keys() else 1
              # rename duplicated keys with °°° number suffix
              for key, val in dict(dupli).items():
                  del dupli[key]
                  if val > 1:
                      for i in range(val):
                          dupli[key+'°°°'+str(i)] = val
                  else: dupli[key] = 1
              # rename columns so that we can now access abmigous column names
              # sorting in dict is the same as in original table
              df.columns = dupli.keys()
              # for each duplicated column name
              for i in set(re.sub('°°°(.*)','',j) for j in dupli.keys() if '°°°' in j):
                  i = str(i)
                  # for each duplicate of a column name
                  for k in range(dupli[i+'°°°0']-1):
                      # concatenate values in duplicated columns
                      df[i+'°°°0'] = df[i+'°°°0'].astype(str) + df[i+'°°°'+str(k+1)].astype(str)
                      # Drop duplicated columns from which we have aquired data
                      df = df.drop(i+'°°°'+str(k+1), 1)
              # resort column names for proper mapping
              df = df.reindex_axis(sorted(df.columns), axis = 1)
              # rename columns
              df.columns = sorted(set(re.sub('°°°(.*)','',i) for i in dupli.keys()))
              return df
          

          【讨论】:

            【解决方案6】:

            如果有帮助,我在尝试连接两个数据帧时也遇到了这个错误(截至撰写本文时,这是除了源代码之外我在 google 上能找到的唯一相关命中)。

            我不知道这个答案是否会解决 OP 的问题(因为他/她没有发布足够的信息),但对我来说,这是当我尝试使用列 concat 数据框 df1 时引起的['A', 'B', 'B', 'C'](查看重复的列标题?)数据框 df2 和列 ['A', 'B']。可以理解的是,重复导致熊猫摇摇晃晃。将df1 更改为['A', 'B', 'C'](即删除重复的列之一),一切正常。

            【讨论】:

            • 有关消除重复列名的帮助,请尝试 Gene Burinsky 对此问题的回答 df = df.loc[:,~df.columns.duplicated()] link
            • 实际上当我们 read_excel 到数据框时... pandas 可以自动处理重复的名称.. 并在重复的列名后添加后缀“.1” “.2” ...仅此问题发生..当我们忽略自动列命名..并编写我们自己的列标题。
            • 请参阅下面的链接,了解如何自动重命名......stackoverflow.com/questions/24685012/…(这对我有用)
            【解决方案7】:

            我最近也收到了这条消息,我发现上面的用户 @jason@user3805082 在我试图 concat 的数百个数据框中有几个重复的列,每个都有几十个神秘的变量名.手动搜索重复项是不切实际的。

            如果其他人有同样的问题,我写了下面的函数可能会有所帮助。

            def duplicated_varnames(df):
                """Return a dict of all variable names that 
                are duplicated in a given dataframe."""
                repeat_dict = {}
                var_list = list(df) # list of varnames as strings
                for varname in var_list:
                    # make a list of all instances of that varname
                    test_list = [v for v in var_list if v == varname] 
                    # if more than one instance, report duplications in repeat_dict
                    if len(test_list) > 1: 
                        repeat_dict[varname] = len(test_list)
                return repeat_dict
            

            然后您可以遍历该 dict 以报告有多少重复项、删除重复的变量或以某种系统的方式重命名它们。

            【讨论】:

            • 您可以通过以下方式识别重复的列:df.loc[:,df.columns.duplicated()]
            • 来吧,很简单-ss = pd.Series(df.columns).value_counts(); ss[ss>1]
            • 或者干脆忽略重复的列:df.loc[:,~df.columns.duplicated()]
            猜你喜欢
            • 2019-06-03
            • 2018-03-03
            • 2019-04-20
            • 2016-05-04
            • 2022-12-07
            • 2020-11-27
            • 2018-03-06
            • 2020-02-19
            • 1970-01-01
            相关资源
            最近更新 更多