Pandas:如何将 MultiIndex DataFrame 与单个索引 DataFrame 连接,以及自定义排序
Posted
技术标签:
【中文标题】Pandas:如何将 MultiIndex DataFrame 与单个索引 DataFrame 连接,以及自定义排序【英文标题】:Pandas: how to concatenate a MultiIndex DataFrame with a single index DataFrame, and custom ordering 【发布时间】:2018-05-13 16:30:47 【问题描述】:我有一个 MultiIndex pandas DataFrame df_multi
像:
import pandas as pd
df_multi = pd.DataFrame([['A', 'A1', 0,234,2002],['A', 'A1', 1,324,2550],
['A', 'A1', 2,345,3207],['A', 'A1', 3,458,4560],['A', 'A2', 0,569,1980],
['A', 'A2', 1,657,2314],['A', 'A2', 2,768,4568],['A', 'A2', 3,823,5761]],
columns=['Product','Scenario','Time','Quantity','Price']).set_index(
['Product', 'Scenario'])
和一个单一的索引 DataFrame df_single
类似:
df_single = pd.DataFrame([['A', -3,100],['A', -2,100], ['A', -1,100]],
columns=['Product','Time','Quantity']).set_index(['Product'])
对于df_multi
的第一级索引中的每个“产品”,以及第二级中的每个“场景”,我想附加/连接df_single
中的行,其中包含一些负的“时间”要在 df_multi
中的正“时间”值之前附加的值开始。
我还希望生成的 DataFrame 首先由 ['Product','Scenario'] 进行多重索引(就像df_multi
),然后是按“时间”值升序排列的行。换句话说,期望的结果是:
df_result = pd.DataFrame([['A', 'A1', -3,100,'NaN'],['A', 'A1', -2,100,'NaN'],
['A', 'A1', -1,100,'NaN'],['A', 'A1', 0,234,2002],['A', 'A1', 1,324,2550],
['A', 'A1', 2,345,3207],['A', 'A1', 3,458,4560],['A','A2', -3,100,'NaN'],
['A', 'A2', -2,100,'NaN'],['A', 'A2', -1,100,'NaN'],['A', 'A2', 0,569,1980],
['A', 'A2', 1,657,2314],['A', 'A2', 2,768,4568],['A', 'A2', 3,823,5761]],
columns=['Product','Scenario','Time','Quantity','Price']).set_index(
['Product', 'Scenario'])
编辑:
df_single
没有“场景”值,这可能会造成混淆。只要 'Product' 匹配,df_single
的相同行将被附加到 df_multi
中的每个场景,它们只是免费“继承”场景值。
我正在使用的实际 DataFrame 相当大(每个产品几千个“产品”,几千个“场景”,每个场景几百个“时间”步骤,加上我没有写在例如),所以我需要以一种完全自动化(希望是快速)的方式来执行此操作。
我尝试使用所有join
、concat
和merge
来实现这一点,但我没有成功。实现预期结果的最佳方法是什么?
【问题讨论】:
df_single中没有Scenario。我们是否为 df_multi 中的每个不同场景平均分割 df_single's 产品行?我们是否保证行将始终像发布的 3 和 3 示例一样均匀分布? 确实在 df_single 中没有场景,因为 df_single 中表示的新行对于每个场景都是相同的。只要“产品”匹配 en df_multi 和 df_single,我想将 df_single 的相同切片附加到 df_multi 中的每个场景,并自动为其分配“当前”场景值。 您知道 df_single 中有重复项吗?如果它们是合法记录,为什么不将所有 6 都附加到 A1 和 A2 场景而不是 3 和 3? 对重复的内容道歉,我在那里遇到了一些复制粘贴问题。我现在已经删除了它们。有没有办法将代码直接在 *** 中生成的 DataFrame 可视化? (如果你想让人们在更大的数据帧上测试它的可扩展性,请将数据帧 sn-ps 编辑为长度为 10**N 行的种子随机数据。额外的列无关紧要很多,忽略它们。) 【参考方案1】:考虑将索引重置为 merge
的列,然后是 groupby
聚合仅返回每个组一次并避免重复。之后,运行串联,concat
,然后进行列排序并设置多索引。
# MERGE AND AGGREGATION
df_temp = df_multi.reset_index().merge(df_single.reset_index(), on='Product', suffixes=['','_'])\
.groupby(['Product', 'Scenario', 'Time_'])['Quantity_'].max()\
.reset_index().rename(columns='Time_':'Time','Quantity_':'Quantity')
# ROW BIND CONCATENATION
df_final = pd.concat([df_multi.reset_index(), df_temp])\
.sort_values(['Product','Scenario', 'Time'])\
.set_index(['Product', 'Scenario'])[['Time', 'Quantity', 'Price']]
print(df_final)
# Time Quantity Price
# Product Scenario
# A A1 -3 100 NaN
# A1 -2 100 NaN
# A1 -1 100 NaN
# A1 0 234 2002.0
# A1 1 324 2550.0
# A1 2 345 3207.0
# A1 3 458 4560.0
# A2 -3 100 NaN
# A2 -2 100 NaN
# A2 -1 100 NaN
# A2 0 569 1980.0
# A2 1 657 2314.0
# A2 2 768 4568.0
# A2 3 823 5761.0
【讨论】:
它有效,谢谢!我对速度/可扩展性很好奇。我将在我使用的真实数据上对其进行测试,以了解它在大型数据帧上的表现。以上是关于Pandas:如何将 MultiIndex DataFrame 与单个索引 DataFrame 连接,以及自定义排序的主要内容,如果未能解决你的问题,请参考以下文章
Pandas:如何将 MultiIndex DataFrame 与单个索引 DataFrame 连接,以及自定义排序
如何更新 MultiIndex pandas DataFrame 的子集
将 MultiIndex Pandas 数据帧乘以来自另一个数据帧的多个标量