如何将 for 循环中的 .pkl 文件附加到 for 循环中创建的 pandas 数据帧?

Posted

技术标签:

【中文标题】如何将 for 循环中的 .pkl 文件附加到 for 循环中创建的 pandas 数据帧?【英文标题】:How to append .pkl files in for loop to pandas dataframe created in for loop? 【发布时间】:2020-10-14 00:13:27 【问题描述】:

我有一段看似简单的代码,但不知何故它不起作用。代码的目标是在文件夹中查找所有泡菜数据,将 for 循环中的第一个作为 pandas 数据框加载,该数据框在以前不存在的变量下命名,如果变量存在,则应加载剩余的泡菜文件作为 pandas 并将它们附加到第一个循环中新创建的 pandas 数据帧:

import pandas as pd
import os

# Creating the first Dataframe using dictionary 
df1  = pd.DataFrame("a":[1, 2, 3, 4], 
                         "b":[5, 6, 7, 8]) 
  
# Creating the Second Dataframe using dictionary 
df2 = pd.DataFrame("a":[1, 2, 3], 
                    "b":[5, 6, 7]) 


df1.append(df2) 

打印效果很好:

    a   b
0   1   5
1   2   6
2   3   7
3   4   8
0   1   5
1   2   6
2   3   7

但是,当我尝试在 for 循环中附加存储的 pickle 文件中的数据帧时,它不会打印错误,但它仅适用于第一个数据帧:

df1.to_pickle("DF1.pkl")
df2.to_pickle("DF2.pkl")

files = [f for f in os.listdir('.') if os.path.isfile(f)]
#The line above should produce the line below
files=["DF1.pkl", "DF2.pkl"]

for i in files:
    if ".pkl" in i:
        if "ALL_DATA" not in globals():
            ALL_DATA=pd.read_pickle(i)
        else:
            ALL_DATA.append(pd.read_pickle(i))

只打印:

a   b
0   1   5
1   2   6
2   3   7
3   4   8

谁能帮我澄清一下?

【问题讨论】:

【参考方案1】:

DataFrame.append 返回一个新对象,因此尽管您调用 ALL_DATA.append(pd.read_pickle(i)) 因为您从未将其写回 ALL_DATA,但这些更改将被丢弃。您需要重新分配更改:

ALL_DATA = ALL_DATA.append(pd.read_pickle(i))

但是,在循环中追加是低效的,因为它会在每次迭代时复制数据,所以你应该避免它。相反,追加到一个列表,这很快,然后在循环之后concat 一次。

l = [] # Holds everything you may possibly append
for i in files:
    if ".pkl" in i:
        if "ALL_DATA" not in globals():
            ALL_DATA=pd.read_pickle(i)
        else:
            l.append(pd.read_pickle(i)) # List append which modifies `l`

# Create df from ALL_DATA and everything that you append
ALL_DATA = pd.concat([ALL_DATA, *l])

【讨论】:

谢谢,这行得通。我确实没有意识到 df.append 返回一个新对象。由于带有泡菜的文件夹很大,因此您更有效的解决方案非常有用:)。

以上是关于如何将 for 循环中的 .pkl 文件附加到 for 循环中创建的 pandas 数据帧?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Vue.js 将 DataTable() 与数组中的数据(v-for 循环)附加到现有的 HTML <table>?

如何在for循环中将数据附加到空列表?

将 for 循环的结果附加到 Laravel 中的 eloquent 输出

如何利用python读取PKL文件

Python for 循环仅将最后一个列表作为值附加

批处理:如何在 FOR 循环中附加字符串