【问题标题】:How to concatenate dataframes without overwriting column values如何在不覆盖列值的情况下连接数据帧
【发布时间】:2021-04-18 02:05:24
【问题描述】:

我正在尝试在 for 循环中创建 DataFrame 列表,然后将它们连接到 for 循环之外并写入 excel。我已经让代码接近了,但由于某种原因,在 for 循环中创建的列最终成为最终值,而不是循环时的每个单独值。我确信这非常简单,我只是错过了一些简单的东西,但今晚似乎无法弄清楚。这里有一些虚拟代码来说明和帮助解决问题。最后,我想要一个 wks 1 - 9 的 excel 输出。但是,在我的实际输出中,wk 列中的所有值都等于 9。

import pandas as pd
sample = []
area = pd.Series({'California':423967, 'Texas':695662})
pop = pd.Series({'California':38332521, 'Texas':26448193})

data = pd.DataFrame({'area':area, 'pop':pop})
print(data)

for i in range(10):
    data['wk'] = i
    sample.append(data)
    print(data)

res = pd.concat(sample)
res.to_excel("Concatenating DataFrames.xlsx", index=False)

【问题讨论】:

  • data['wk'] 是一列,而不是一个元素,但您正试图为其分配一个值,在这种情况下,pandas 将使用相同的值填充该列的所有行。
  • 我不确定我是否完全按照。我知道这是一个专栏。但是,我认为通过将其写入 DataFrames 列表然后将它们连接起来,它会保留它的价值。例如,当我 print(data) 显示第 1 周的第一个 DataFrame,第 2 周的第二个 DataFrame 等。最终将 DataFrame 列表连接在一起时,如何保留这些值?

标签: python pandas dataframe for-loop concatenation


【解决方案1】:

问题在于,当您将数据附加到列表时,它不会为其创建单独的内存,而是它们都引用相同的内存,这就是为什么在循环中最后一次更新后它变为 9 或最终值的原因。

只是替换

sample.append(data)

sample.append(data.copy())

.copy() 将强制 pandas 为循环中的每个 df 创建新内存

【讨论】:

  • 我不是专业的程序员,但是有什么学习内存和内存分配的最佳实践吗?我错误地认为它每次都会将数据框写入列表,从而保留数据框所具有的任何周值。显然,我错了,但希望能有任何想法或建议,以更好地理解它为什么这样做并理解内存/内存分配。
【解决方案2】:

在一个循环中制作多个数据帧并将它们连接起来是非常低效的。最好在列表或字典上进行迭代,然后在循环之后创建一个数据框。为此,我在下面将您的系列转换回字典。请注意,必须在循环的每次迭代中复制字典,以便循环不会不断改变原始字典。

import pandas as pd
import openpyxl
from copy import deepcopy

area = pd.Series({'California':423967, 'Texas':695662})
pop = pd.Series({'California':38332521, 'Texas':26448193})
area_d = area.to_dict()
pop_d = pop.to_dict()

sample = []
for i in range(10):
    area_copy = deepcopy(area_d)
    pop_copy = deepcopy(pop_d)
    area_copy['wk'] = i
    pop_copy['wk'] = i
    sample += [area_copy, pop_copy]
df = pd.DataFrame(sample)
df.to_excel("result.xlsx", index = False)

【讨论】:

  • 当区域和流行音乐是静态的时,我发现这是可行的。在我的现实生活场景中,基础数据发生了变化。例如,它按第一周汇总销售额并计算平均值和排名。然后它第二次循环,从第 1-2 周提取数据,并在数周内重复该过程等。这种情况会起作用吗?我假设不会,因为这个例子中的 area 和 pop 会随着每个 for 循环而改变。这就是为什么我创建了一个数据帧列表以在循环外连接,但我很高兴听到更多内存效率更高的方法,因为我仍在学习。
  • @ShawnSchreier 我相当肯定它会起作用。提供一个更真实地捕捉您的工作流程的示例,我们可以查看它。
猜你喜欢
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 1970-01-01
  • 2022-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多