有效获取Pandas联合指数

2024-05-16 07:16:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个pandas数据帧df1和{},我想要它们的“合并索引”。在

我所说的索引是指当我这样做时获得的索引,例如df1.add(df2, fill_value=0).index(基本上是行名称的联合)。这种计算(这里,add)是在单独的脚本中执行的,我不想在这些脚本中计算“合并索引”,但我也希望避免在我对“合并索引”感兴趣时进行这些计算。在

有没有一种更“直接”(希望是有效的)的方式来做到这一点?

我的目标实际上是将“标记”与索引元素关联起来。我有几对数据帧。每对对应于一个“标签”,并且可能有重叠的索引。不同的对对应着不同的标签,它们应该没有重叠的索引。在

基本上,我在寻找一个associate_tag函数的有效实现,其工作原理如下:

dfA_1

idA_1    2    0
idA_2    1    0
idA_3    0    2

dfA_2

^{pr2}$

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轻松地将一个“tag”列添加到包含混合索引元素的数据帧中。例如,我可以:

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

有更好的方法来做这种手术吗?在


Tags: 数据addindexdeftagmergeassociatedataframes
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)

根据您的意见,这里有一个修正的解决方案:

两部分: 根据列名组合数据帧,可以帕金森病确保列名对齐后,您的整个数据帧列表。所以如果: dfA_1是:

       col1  col2
index            
idA_1     2     0
idA_2     1     0
idA_3     0     2

以及 dfA_2是:

^{pr2}$

那么

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

用0填充这些nan:

final.fillna(0, inplace=True)

第2部分,标签: 一旦您知道创建标记就像为索引定义映射一样简单,您可以编写一个简单的函数、硬编码dict或使用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

相关问题 更多 >