错误“‘DataFrame’对象没有属性‘append’”

2024-12-09 08:30:00
admin
原创
159
摘要:问题描述:我正在尝试将字典附加到 DataFrame 对象,但出现以下错误:AttributeError:'DataFrame'对象没有属性'append'据我所知,DataFrame 确实有“append”方法。代码片段:df = pd.DataFrame(df).append(new_row, ignor...

问题描述:

我正在尝试将字典附加到 DataFrame 对象,但出现以下错误:

AttributeError:'DataFrame'对象没有属性'append'

据我所知,DataFrame 确实有“append”方法。

代码片段:

df = pd.DataFrame(df).append(new_row, ignore_index=True)

我希望字典new_row能作为新行添加。

我该如何修复它?


解决方案 1:

从 pandas 2.0 开始,append(之前已弃用)已被删除。

您需要使用concat(对于大多数应用程序):

df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True)

正如 @cottontail 所指出的,也可以使用loc,但这仅在新索引尚未存在于 DataFrame 中时才有效(通常,如果索引是,就会出现这种情况RangeIndex

df.loc[len(df)] = new_row # only use with a RangeIndex!

为什么它被删除了?

我们经常看到熊猫尝试像使用纯 Python 那样编写代码。他们习惯于iterrows在循环中访问项目(请参阅此处了解为什么不应该这样做),或者append以类似于 python 的方式访问项目list.append

但是,正如 pandas 问题#35407中所述,pandas 的appendlist.append实际上并不是一回事list.append已经到位,而 pandasappend会创建一个新的 DataFrame:

我认为我们应该弃用 Series.append 和 DataFrame.append。它们与 list.append 进行了类比,但这种类比并不恰当,因为这种行为并不适用(也不可能适用)。需要复制索引和值的数据才能创建结果。

这些显然也是很​​流行的方法。DataFrame.append 在我们的 API 文档中访问量排名第 10 位。

除非我弄错了,否则用户最好总是建立一个值列表并将它们传递给构造函数,或者建立一个 NDFrames 列表然后进行单个连接。

因此,虽然在循环的每一步中摊销的时间list.append都是O(1) ,但pandas 的摊销append时间是O(1) O(n),这在执行重复插入时效率低下

如果我需要重复这个过程该怎么办?

重复使用appendconcat并不是一个好主意(这具有二次行为,因为它为每个步骤创建一个新的 DataFrame)。

在这种情况下,应将新项目收集到列表中,并在循环结束时转换为DataFrame原始项目并最终连接到原始项目DataFrame

lst = []

for new_row in items_generation_logic:
    lst.append(new_row)

# create extension
df_extended = pd.DataFrame(lst, columns=['A', 'B', 'C'])
# or columns=df.columns if identical columns

# concatenate to original
out = pd.concat([df, df_extended])

解决方案 2:

免责声明:这个答案似乎很受欢迎,但不应使用建议的方法。append更改_append_append是一种私有内部方法,append已从pandas API 中删除。 声称appendpandas 中的方法看起来类似于Python 中的list.append。 这就是 pandas 中的 append 方法现在被修改为 的原因_append。”是完全错误的。 前导_仅表示一件事:该方法是私有的,不打算在 pandas 的内部代码之外使用。


在新版本的Pandas中,该append方法改为_append。您可以直接使用_append而不是append,即df._append(df2)

df = df1._append(df2,ignore_index=True)

为什么会改变呢?

pandas 中的方法与 Python 中的list.appendappend类似。因此, pandas 中的append方法现在被修改为。_append

解决方案 3:

DataFrame.append如果您使用或concat或循环扩大数据框loc,请考虑重写代码以扩大 Python 列表并构造一次数据框。有时,您甚至可能不需要pd.concat,您可能只需要在字典列表上使用 DataFrame 构造函数。

将新行附加到数据框的一个非常常见的例子是从网页中抓取数据并将其存储在数据框中。在这种情况下,不是附加到数据框,而是用列表替换数据框,然后在末尾调用一次pd.DataFrame()pd.concat一次。例如:

因此,不要:

df = pd.DataFrame()       # <--- initial dataframe (doesn't have to be empty)
for url in ticker_list:
    data = pd.read_csv(url)
    df = df.append(data, ignore_index=True)  # <--- enlarge dataframe

使用:

lst = []                  # <--- initial list (doesn't have to be empty; 
for url in ticker_list:   #                    could store the initial df)
    data = pd.read_csv(url)
    lst.append(data)                         # <--- enlarge list
df = pd.concat(lst)                          # <--- concatenate the frames

数据读取逻辑可以是来自 API 的响应数据、从网页抓取的数据,无论什么,代码重构都非常少。在上面的例子中,我们假设这lst是一个数据框列表,但如果它是一个字典/列表等列表,那么我们可以df = pd.DataFrame(lst)在最后一行代码中使用它。


也就是说,如果要将一行附加到数据框,loc也可以完成这项工作。

df.loc[len(df)] = new_row

通过调用loc,数据框会用索引标签扩大len(df),这仅在索引为时才有意义RangeIndexRangeIndex如果没有将显式索引传递给数据框构造函数,则默认创建。

一个工作示例:

df = pd.DataFrame({'A': range(3), 'B': list('abc')})
df.loc[len(df)] = [4, 'd']
df.loc[len(df)] = {'A': 5, 'B': 'e'}
df.loc[len(df)] = pd.Series({'A': 6, 'B': 'f'})

结果

正如 @mozway 所指出的,扩大 pandas 数据框的复杂度为 O(n^2),因为在每次迭代中,必须读取和复制整个数据框。以下 perfplot 显示了相对于一次连接而言的运行时间差异。1如您所见,扩大数据框的两种方法都比扩大列表和构建数据框慢得多(例如,对于具有 10k 行的数据框,concat循环速度大约慢 800 倍,loc循环速度大约慢 1600 倍)。

性能图

1用于生成 perfplot 的代码:

import pandas as pd
import perfplot

def concat_loop(lst):
    df = pd.DataFrame(columns=['A', 'B'])
    for dic in lst:
        df = pd.concat([df, pd.DataFrame([dic])], ignore_index=True)
    return df.infer_objects()
    
def concat_once(lst):
    df = pd.DataFrame(columns=['A', 'B'])
    df = pd.concat([df, pd.DataFrame(lst)], ignore_index=True)
    return df.infer_objects()

def loc_loop(lst):
    df = pd.DataFrame(columns=['A', 'B'])
    for dic in lst:
        df.loc[len(df)] = dic
    return df


perfplot.plot(
    setup=lambda n: [{'A': i, 'B': 'a'*(i%5+1)} for i in range(n)],
    kernels=[concat_loop, concat_once, loc_loop],
    labels= ['concat in a loop', 'concat once', 'loc in a loop'],
    n_range=[2**k for k in range(16)],
    xlabel='Length of dataframe',
    title='Enlarging a dataframe in a loop',
    relative_to=1,
    equality_check=pd.DataFrame.equals);
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用