Pandas 连接具有相同行索引的多索引列
Posted
技术标签:
【中文标题】Pandas 连接具有相同行索引的多索引列【英文标题】:Pandas concatenate Multiindex columns with same row index 【发布时间】:2021-02-22 21:28:57 【问题描述】:我想连接 NumPy 计算的多维输出,其维度与输入的形状匹配(关于行和相应的选定列)。
但它失败了:NotImplementedError: Can only union MultiIndex with MultiIndex or Index of tuples, try mi.to_flat_index().union(other) instead
。
我不想先将索引变平 - 那么还有其他方法可以让它工作吗?
import pandas as pd
from pandas import Timestamp
df = pd.DataFrame(('metrik_0', Timestamp('2020-01-01 00:00:00')): (1, 1): 2.5393693602911447, (1, 5): 4.316896324314225, (1, 6): 4.271001191238499, (1, 9): 2.8712588011247377, (1, 11): 4.0458495954752545, ('metrik_0', Timestamp('2020-01-01 01:00:00')): (1, 1): 4.02779063729038, (1, 5): 3.3849606155101224, (1, 6): 4.284114856052976, (1, 9): 3.980919941298365, (1, 11): 5.042488191587525, ('metrik_0', Timestamp('2020-01-01 02:00:00')): (1, 1): 2.374592085569529, (1, 5): 3.3405503781564487, (1, 6): 3.4049690284720366, (1, 9): 3.892686173978996, (1, 11): 2.1876998087043127)
def compute_return_columns_to_df(df, colums_to_process,axis=0):
method = 'compute_result'
renamed_base_levels = map(lambda x: f'x_method', colums_to_process.get_level_values(0).unique())
renamed_columns = colums_to_process.set_levels(renamed_base_levels, level=0)
#####
# perform calculation in numpy here
# for the sake of simplicity (and as the actual computation is irrelevant - it is omitted in this minimal example)
result = df[colums_to_process].values
#####
result = pd.DataFrame(result, columns=renamed_columns)
display(result)
return pd.concat([df, result], axis=1) # fails with: NotImplementedError: Can only union MultiIndex with MultiIndex or Index of tuples, try mi.to_flat_index().union(other) instead.
# I do not want to flatten the indices first - so is there another way to get it to work?
compute_return_columns_to_df(df[df.columns[0:3]].head(), df.columns[0:2])
【问题讨论】:
你的预期输出是什么? 非常类似于***.com/questions/49277682/… 我只是想将其添加为列。当然可以迭代所有列并添加它 - 但我更愿意一次将所有列添加到源数据框中。 即对于 result.columns 中的 col: df[col] = result[col] return df 当然可以。但需要迭代。 【参考方案1】:你的代码失败的原因在:
result = df[colums_to_process].values
result = pd.DataFrame(result, columns=renamed_columns)
请注意,结果有:
具有***索引级别的列名重命名为 metrik_0_compute_result(目前还可以), 但行索引是默认的单级索引, 由连续的数字组成。然后,当您连接 df 和 result 时,Pandas 会尝试 在行索引上对齐两个源 DataFrame,但它们不兼容 (df 有一个 MultiIndex,而 result 有一个“普通”索引)。
将这部分代码更改为:
result = df[colums_to_process]
result.columns = renamed_columns
这种方式 result 保持原来的索引和 concat 提出 no 例外。
另外说明:你的函数包含 axis 参数,即 没用过。考虑删除它。
另一种可能的方法
由于 result 有一个默认(单级)索引,您可以将 代码的前一部分按原样,但在加入之前重置 df 中的索引:
return pd.concat([df.reset_index(drop=True), result], axis=1)
这样,两个 DataFrame 具有相同的索引,您可以连接 他们也是。
【讨论】:
这不起作用 - 正如我所说的操作正在 numpy 上工作(= 隐式地删除了 pandas 的原始索引)。所以你是对的 - 但不幸的是,大纲解决方案仅适用于基于 pandas 的简单虚拟示例。以上是关于Pandas 连接具有相同行索引的多索引列的主要内容,如果未能解决你的问题,请参考以下文章