我有两个pandas数据帧df1
和df2
,我希望他们的"合并索引"。
我的意思是当我做例如df1.add(df2, fill_value=0).index
时获得的索引(基本上是行名称的联合)。这种计算(这里,add
)是在单独的脚本中执行的,我不想计算"合并索引"在这些脚本中,但我还想避免在我对#34;合并索引"感兴趣时进行这些计算。
还有更多"直接" (并希望有效率)这样做的方式?
我的目标实际上是关联"标签"索引元素。我有几对数据帧。每对对应一个标签"并且可能有重叠的指数。不同的对应对应不同的标签,并且它们应该没有重叠的索引。
基本上,我正在寻找一种有效的associate_tag
函数实现,该函数的工作原理如下:
dfA_1
:
idA_1 2 0
idA_2 1 0
idA_3 0 2
dfA_2
:
idA_1 3 2 1
idA_3 2 6 2
idA_4 4 0 2
merge_A = associate_tag((dfA_1, dfA_2), "A")
:
idA_1 A
idA_2 A
idA_3 A
idA_4 A
dfB_1
:
idB_1 2 2 1
idB_2 3 0 0
idB_3 3 1 3
dfB_2
:
idB_1 0
idB_2 3
idB_4 2
merge_B = associate_tag((dfB_1, dfB_2), "B")
:
idB_1 B
idB_2 B
idB_3 B
idB_4 B
total_merge = pd.concat((merge_A, merge_B))
:
idA_1 A
idA_2 A
idA_3 A
idA_4 A
idB_1 B
idB_2 B
idB_3 B
idB_4 B
我知道要与给定数据帧对的索引元素关联的标记,associate_tag
函数理想地完全忽略数据帧中的数字。
这是一个非理想的实现:
from functools import reduce
from itertools import repeat
def add_dataframes(df1, df2):
return df1.add(df2, fill_value=0)
def sum_dataframes(dfs):
return reduce(add_dataframes, dfs)
def associate_tag(dfs, tag):
return pd.concat((sum_dataframes(dfs).index, repeat(tag)), axis=1)
def associate_tag(dfs, tag):
s = sum_dataframes(dfs)
return pd.DataFrame(list(zip(s.index, repeat(tag)))).set_index(0)
我打算使用此total_merge
轻松添加"标记"列到包含索引元素混合的数据帧。例如,我可以:
df
:
idA_2 5 4 1
idB_1 1 0 0
idB_4 2 1 2
idA_4 2 3 2
然后我会使用pd.concat((df, total_merge), join="inner", axis=1)
添加带标签的额外列:
idA_2 5 4 1 A
idB_1 1 0 0 B
idB_4 2 1 2 B
idA_4 2 3 2 A
有没有更好的方法来进行这种操作?
答案 0 :(得分:2)
我终于发现pandas Index
对象实现了__or__
。
希望以下版本的associate_tag
避免多余的操作:
from operator import or_ as union
from itertools import repeat
from functools import reduce
def associate_tag(dfs, tag):
idx = reduce(union, (df.index for df in dfs))
return pd.DataFrame(list(zip(idx, repeat(tag)))).set_index(0)
答案 1 :(得分:0)
根据您的评论,这是一个经过修改的解决方案:
两部分: 结合您的数据框架,根据您的列名称,一旦确定列名称排列,您就可以pd.concat整个数据框列表。因此,如果: dfA_1是:
col1 col2
index
idA_1 2 0
idA_2 1 0
idA_3 0 2
和 dfA_2是:
col1 col2 col3
index
idA_1 3 2 1
idA_3 2 6 2
idA_4 4 0 2
然后
final = pd.concat([dfA_1,dfA_2])
final
col1 col2 col3
index
idA_1 2 0 NaN
idA_2 1 0 NaN
idA_3 0 2 NaN
idA_1 3 2 1.0
idA_3 2 6 2.0
idA_4 4 0 2.0
用零填充这些NaN:
final.fillna(0, inplace=True)
第2部分,标签: 一旦你创建了标签就像为索引定义一个地图一样简单,你可以写一个简单的函数,硬编码一个字典,或者使用一个lambda:
final['tag'] = final.index.map(lambda x: x[2])
final
col1 col2 col3 tag
index
idA_1 2 0 0.0 A
idA_2 1 0 0.0 A
idA_3 0 2 0.0 A
idA_1 3 2 1.0 A
idA_3 2 6 2.0 A
idA_4 4 0 2.0 A