在熊猫中连接/附加许多数据帧
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】:
那是因为您有效地将字符串附加到您的列表中。如果你有命名变量,df1
到df20
,你可以使用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 更新了帖子。感谢您是否可以查看它并帮助修复它,因为我做错了什么。谢谢! 没有必要有一个列表,当打印出来时,它会显示里面的变量,只显示它们的名字,就好像你在编码一样。请看我更新的答案。以上是关于在熊猫中连接/附加许多数据帧的主要内容,如果未能解决你的问题,请参考以下文章