在具有循环或 lambda 的多个数据帧中添加具有相同字符串值的列的更有效方法?
Posted
技术标签:
【中文标题】在具有循环或 lambda 的多个数据帧中添加具有相同字符串值的列的更有效方法?【英文标题】:More efficient way to add columns with same string values in multiple dataframes with loops or lambdas? 【发布时间】:2020-10-28 00:11:27 【问题描述】:我想在我的 8 个相似数据框中的每一个中添加一个新列 Category。
此列中的值相同,它们也是 df 名称,如本例中的df1_p8
。
我用过:
In: df61_p8.insert(3,"Category","df61_p8", True)
# or simply, df61_p8['Category']='df61_p8'
Out:
code violation_description Category
89491 9-1-503 Defective or obstructed duct system one- building df61_p8
102045 9-1-503 Defective or obstructed duct system one- building df61_p8
103369 9-1-503 Defective or obstructed duct system one- building df61_p8
130440 9-1-502 Failure to maintain at least one (1) elevator df61_p8
132446 9-1-503 Defective or obstructed duct system one- building df61_p8
最终,我想将这 8 个数据帧附加/连接到一个数据帧中。
我想知道是否有更有效的方法来做到这一点,而不是在每个数据帧上一个一个地使用 .insert。 循环或 lambda 之类的东西。作为初学者,我不确定如何在我的情况下应用它们?谢谢。
append_alldfs = []
x=[df61_p1,df61_p2,df61_p3,df61_p4,df61_p5,df61_p6,df61_p7,df61_p8]
lambdafunc = lambda x: x.insert(3,"Category","x",True)
【问题讨论】:
【参考方案1】:def add_column(df, col_name, col_value):
return df.insert(loc=-1, column=col_name, value=col_value, allow_duplicates = False)
df_list = [........]
col_name = ...
col_value = .... # copy column (Category) values
res = map(lambda df: add_column(df, col_name, col_value), df_list)
list(res)
【讨论】:
你的答案正是我所希望的......但是,我无法让它工作,因为它给了我一个空输出 是的,使用list(map_object)
,我已经更新了答案
map()
,比使用循环更高效【参考方案2】:
您可以使用pd.concat
和keys
参数,然后使用reset_index
:
pd.concat([df0,df1,df2,df3], keys=['df0', 'df1', 'df2', 'df3']).reset_index(level=0)
MCVE:
df0 = pd.DataFrame(np.ones((3,3)), columns=[*'ABC'])
df1 = pd.DataFrame(np.zeros((3,3)), columns=[*'ABC'])
df2 = pd.DataFrame(np.zeros((3,3))+3, columns=[*'ABC'])
df3 = pd.DataFrame(np.zeros((3,3))+4, columns=[*'ABC'])
df_out = pd.concat([df0,df1,df2,df3], keys=['df0', 'df1', 'df2', 'df3']).reset_index(level=0)
df_out
输出:
level_0 A B C
0 df0 1.0 1.0 1.0
1 df0 1.0 1.0 1.0
2 df0 1.0 1.0 1.0
0 df1 0.0 0.0 0.0
1 df1 0.0 0.0 0.0
2 df1 0.0 0.0 0.0
0 df2 3.0 3.0 3.0
1 df2 3.0 3.0 3.0
2 df2 3.0 3.0 3.0
0 df3 4.0 4.0 4.0
1 df3 4.0 4.0 4.0
2 df3 4.0 4.0 4.0
【讨论】:
@bluetail 是的,这会创建一个 pd.MultiIndex 然后你在一个级别上 reset_index。【参考方案3】:保持简单明了。
for col_val, df in [
('df61_p1', df61_p1),
('df61_p2', df61_p2),
('df61_p3', df61_p3),
('df61_p4', df61_p4),
('df61_p5', df61_p5),
('df61_p6', df61_p6),
('df61_p7', df61_p7),
('df61_p8', df61_p8),
]:
df['Category'] = col_val
虽然there are certainly more 'meta-programming-ey' ways of accomplishing the same task,但这些通常相当复杂,更难理解和重构。
但是,考虑到这段代码的结构,我想在你到达这一点之前,有一些方法可以解决这个问题。
例如,这些数据帧是在什么时候被拆分的?也许通过从不使用单独的 DataFrames [将原始数据帧保持在一起/在开始时 concat](并根据需要使用 apply、groupby、pivot 和 melt 操作),您可以完全避免这个问题。
【讨论】:
这超出了我的 Coursera 练习范围。我问这个问题只是为了学习如何去做。 :) 感谢您的回答,我无法决定是选择您的还是 concat 海报以获得最佳解决方案!以上是关于在具有循环或 lambda 的多个数据帧中添加具有相同字符串值的列的更有效方法?的主要内容,如果未能解决你的问题,请参考以下文章