如何将一个pandas DataFrame附加到另一个DataFrame?

60

我在数据框追加方面遇到了问题。 我尝试执行以下代码

df_all = pd.read_csv('data.csv', error_bad_lines=False, chunksize=1000000)
urls = pd.read_excel('url_june.xlsx')
substr = urls.url.values.tolist()
df_res = pd.DataFrame()
for df in df_all:
    for i in substr:
        res = df[df['url'].str.contains(i)]
        df_res.append(res)

当我尝试保存df_res时,我得到了一个空的数据框。df_all看起来像

ID,"url","used_at","active_seconds"
b20f9412f914ad83b6611d69dbe3b2b4,"mobiguru.ru/phones/apple/comp/32gb/apple_iphone_5s.html",2015-10-01 00:00:25,1
b20f9412f914ad83b6611d69dbe3b2b4,"mobiguru.ru/phones/apple/comp/32gb/apple_iphone_5s.html",2015-10-01 00:00:31,30
f85ce4b2f8787d48edc8612b2ccaca83,"4pda.ru/forum/index.php?showtopic=634566&view=getnewpost",2015-10-01 00:01:49,2
d3b0ef7d85dbb4dbb75e8a5950bad225,"shop.mts.ru/smartfony/mts/smartfon-smart-sprint-4g-sim-lock-white.html?utm_source=admitad&utm_medium=cpa&utm_content=300&utm_campaign=gde_cpa&uid=3",2015-10-01 00:03:19,34
078d388438ebf1d4142808f58fb66c87,"market.yandex.ru/product/12675734/spec?hid=91491&track=char",2015-10-01 00:03:48,2
d3b0ef7d85dbb4dbb75e8a5950bad225,"avito.ru/yoshkar-ola/telefony/mts",2015-10-01 00:04:21,4
d3b0ef7d85dbb4dbb75e8a5950bad225,"shoppingcart.aliexpress.com/order/confirm_order",2015-10-01 00:04:25,1
d3b0ef7d85dbb4dbb75e8a5950bad225,"shoppingcart.aliexpress.com/order/confirm_order",2015-10-01 00:04:26,9

urls看起来像这样

url
shoppingcart.aliexpress.com/order/confirm_order
ozon.ru/?context=order_done&number=
lk.wildberries.ru/basket/orderconfirmed
lamoda.ru/checkout/onepage/success/quick
mvideo.ru/confirmation?_requestid=
eldorado.ru/personal/order.php?step=confirm

当我在循环中打印res时,它并不为空。但是当我尝试在追加后在循环中打印df_res时,它返回一个空的数据框。 我找不到错误所在。我该如何修复它?

1
对于在收到“为什么会出现'AttributeError: 'DataFrame' object has no attribute 'append'?”后来到此帖子的新用户:从pandas >= 2.0开始,已经从API中删除了append,以防止在循环内迭代地附加数据框。2023年附加数据框的惯用方法是首先将数据汇总到Python列表中,然后调用pd.concat。更多信息 - cs95
3个回答

89

如果您查看pd.DataFrame.append的文档

将其他行附加到此框架末尾,返回一个新对象。 不在此框架中的列将作为新列添加。

(强调是我的)。

尝试一下

df_res = df_res.append(res)

顺便提一下,注意pandas不适合通过连续拼接创建DataFrame,你可以尝试使用以下方法代替:

all_res = []
for df in df_all:
    for i in substr:
        res = df[df['url'].str.contains(i)]
        all_res.append(res)

df_res = pd.concat(all_res)
这首先创建一个所有部件的列表,然后在最后一次性从它们中创建一个DataFrame。

2
谢谢您的解释。有时候 df_res.append(res) 可以工作,但有时只有 df_res = df_res.append(res) 才能工作。但我不知道为什么会发生这种情况。 - Petr Petrov
@PetrPetrov 你是在交互式环境中工作吗? - Ami Tavory
3
+1 指出在循环中使用此方法连接多个数据框的低效性,这让我在代码中一再发现,令我感到疯狂。 - josemz
自1.5版本起,append已被弃用。 https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.append.html - AugustusCaesar

16

为什么会出现“AttributeError: 'DataFrame' object has no attribute 'append'”错误?

pandas >= 2.0已经移除了append,请使用pd.concat1

从pandas 2.0开始,API中已经移除了append。它在1.4版本中已被弃用。请参阅Deprecations文档以及最初提出其弃用的this github issue

移除它的原因是为了防止在循环中迭代增长数据帧(这通常是人们使用append的方式)。这是因为每个阶段都会产生一个新的副本,导致内存呈二次复杂度。

1. 这假设您正在将一个 DataFrame 附加到另一个 DataFrame。如果您要将一行附加到 DataFrame,则解决方案略有不同 - 请参见以下内容。


将多个较小的DataFrame收集到一个列表中,然后进行一次pd.concat调用是连接DataFrame的惯用方式。以下是一个(过度简化的)例子

df_list = []
for df in some_function_that_yields_dfs():
    df_list.append(df)

final_df = pd.concat(df_list)

请注意,如果您想逐行添加而不是一次添加一个DataFrame,解决方案会更简单。
data = []
for a, b, c from some_function_that_yields_data():
    data.append([a, b, c])

df = pd.DataFrame(data, columns=['a', 'b', 'c'])

更多信息请参见如何创建一个空的Pandas DataFrame,并填充它?


5

如果我们想要根据索引添加:

df_res = pd.DataFrame(data = None, columns= df.columns)

all_res = []

d1 = df.ix[index-10:index-1,]     #it will take 10 rows before i-th index

all_res.append(d1)

df_res = pd.concat(all_res)

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