在熊猫中连接/附加许多数据帧

Posted

技术标签:

【中文标题】在熊猫中连接/附加许多数据帧【英文标题】:Concatenate/Append many dataframes in pandas 【发布时间】:2021-07-30 00:20:35 【问题描述】:

我有一个从循环创建的数据帧 df1 到 df20 的列表,我需要一次性连接所有这些数据帧。这些数据帧是动态的,根据我的代码中生成的循环,可以是 1 到 20 之间的任意数字。

所以,我首先尝试创建一个空列表并将这些数据帧名称添加到其中(以 1 到 20 的循环为例)并在 pd.concat(df_list) 中使用此列表,如下所示:

df_list=[]
for in in range(1,21):
    df_list.append(f'dfi')

pd.concat(df_list)

上面的代码正在创建数据帧名称列表,但是以带有引号的字符串形式,如下所示,我无法使用 pd.concat(df_list) 连接数据帧,因为它将所有数据帧名称视为字符串元素

print(df_list)

['df1', 'df2', 'df3', 'df4', 'df5', 'df6', 'df7', 'df8', 'df9', 'df10', 'df11', 'df12', 'df13', 'df14', 'df15', 'df16', 'df17', 'df18','df19','df20']

如果有人可以帮助我获得这种数据帧的连接,请不胜感激。

我想如果我可以添加不带引号的数据框名称,例如 df_list=[df0,df1,df2...] 那么 pd.concat 可以工作,否则请告诉我是否有任何最佳选择来获得这个完毕。谢谢!

更新 根据评论的建议,我创建了一个简单的循环来创建多个数据帧,然后我尝试将“这些数据帧的名称”附加到这个循环本身的一个空列表中,这些数据帧正在被创建。但是,o/p 不是我所期望的。

mylist=[]
for x in range(1,4):
    globals()[f"dfi"]=pd.DataFrame(np.random.randint(99,size=(3,3)),columns=['AA','BB','CC'])
    mylist.append(globals()[f"dfi"])

上面的代码创建了 3 个数据帧 df1、df2 和 df3,并且空列表被追加,但数据帧的内容如下所示

print(mylist)
[   AA  BB  CC
0  57  92  50
1  33  47  28
2  82  77  46,    AA  BB  CC
0  18   8  75
1   1  15  52
2   4  69  38,    AA  BB  CC
0  19  24  31
1  24  52  62
2  50   8  63]

但是,我想要的输出不是数据帧的内容,而是数据帧本身的名称,如下所示。

print(mylist)
[df1,df2,df3]

如果有人能告诉我如何完成这项工作,不胜感激。我认为必须有一些简单的方法来做到这一点。

【问题讨论】:

您应该在创建 DataFrame 的循环期间填充列表,这样您就没有 1-20 个随机变量浮动。如果您想通过某些功能/名称引用它们,那么您可以使用dict,其中键是该标签而不是列表索引。 您要做的是在生成它们时将它们捕获到一个列表中,然后连接该列表。通过字符串表示来引用 vars 通常是不好的做法 @ALollz 你能举例说明你的建议吗? 【参考方案1】:

那是因为您有效地将字符串附加到您的列表中。如果你有命名变量,df1df20,你可以使用locals()(或globals(),这取决于你的命名变量在哪里,以及你是否在函数中连接数据帧)来访问它们。这是一个例子,

df1 = 0
df2 = 1
df3 = 2

df_list = []
for i in range(1, 4):
    df_list.append(locals()[f'dfi'])

>>> df_list
    [0, 1, 2]

编辑:我认为你想要做的是:

import pandas as pd
import numpy as np

mylist = []
for x in range(1, 4):
    df = pd.DataFrame(np.random.randint(99, size=(3,3)), columns=['AA','BB','CC'])
    mylist.append(df)
    
dfs = pd.concat(mylist)

请注意,打印mylist 永远不会告诉您类似mylist = [df1, df2, df3] 的内容,即使您对其进行了硬编码。这将打印列表中所有变量的全部内容。如果由于某种原因您不知道要连接多少个数据帧,那么当您想停止创建数据帧时,只需实现 while 循环即可。

考虑另一个例子

# create a list of 100 dataframes (df0 to df99)
mylist = []
for x in range(100):
    df = pd.DataFrame(np.random.randint(99,size=(3,3)), columns=['AA','BB','CC'])
    mylist.append(df)

concat_range = input("Range of dataframes to concatenate (0-100): ")
i, j = concat_range.split(" ")

dfs = pd.concat(mylist[int(i) : int(j)])

# further operations on dfs

现在,假设我是用户,我想将 df5 连接到 df32

>>> Range of dataframes to concatenate (0-100): 5 32
>>> dfs
    AA  BB  CC
    0   28  37  36
    1   34  18  14
    2   39  41  97
    0   44  66  76
    1   57  16   3
    ..  ..  ..  ..
    1   43  87  74
    2   67  70  73
    0   40  60  57
    1   23  63  70
    2   96  24  31
    
    [81 rows x 3 columns]

【讨论】:

谢谢@Camilo Martinez:但是,df1,df2,df3 .....这些是我的数据框,我没有分配任何值,如您所示。我需要的是根据从循环中创建的数量来连接所有这些数据帧。因此,它们可以是 df1,df2..df5 或高达 df10 或 df20,我想像 pd.concat([df1,df2,df3,df4....]) 一样一次性连接所有这些但没有硬编码因为我不知道他们能有多少。 如果您已经在循环中创建它们,是什么阻止您在创建它们时将它们附加到列表中?一般来说,当您可以使用 Python 的数据结构(如列表、元组或字典)时,请避免使用此类命名变量。 我已经按照您的建议(我认为)进行了尝试,并用实际的 o/p 与预期的 o/p 更新了帖子。感谢您是否可以查看它并帮助修复它,因为我做错了什么。谢谢! 没有必要有一个列表,当打印出来时,它会显示里面的变量,只显示它们的名字,就好像你在编码一样。请看我更新的答案。

以上是关于在熊猫中连接/附加许多数据帧的主要内容,如果未能解决你的问题,请参考以下文章

如何将每一行熊猫数据帧附加到另一个数据帧的每一行

如何将字典附加到熊猫数据框?

在熊猫中分组,转置和附加?

熊猫数据框未附加

使用熊猫在数据框中追加一个空行

熊猫,附加到excel中的下一个可用行[重复]