我是 Pandas 的新手,曾尝试浏览文档并尝试各种示例,但我正在解决的这个问题真的让我很难过。
我有以下两个数据帧(DataA/DataB),我想在每个 global_index/item/values 的基础上合并它们。
DataA DataB
row item_id valueA row item_id valueB
0 x A1 0 x B1
1 y A2 1 y B2
2 z A3 2 x B3
3 x A4 3 y B4
4 z A5 4 z B5
5 x A6 5 x B6
6 y A7 6 y B7
7 z A8 7 z B8
项目列表(item_ids)是有限的,两个数据帧中的每一个都表示给定 global_index 值的项目的特征值(特征 A,特征 B)。
global_index 大致可以被认为是一个“时间”单位
每个数据帧(DataA/DataB)和 global_index 之间的映射是通过以下两个映射器 DF 完成的:
DataA_mapper
global_index start_row num_rows
0 0 3
1 3 2
3 5 3
DataB_mapper
global_index start_row num_rows
0 0 2
2 2 3
4 5 3
简单地说,对于给定的 global_index(例如:1),映射器会将行列表定义到与该 global_index 相关联的各个 DF(DataA 或 DataB)中。
例如,对于 global_index 值为 0:
另一个示例,对于 global_index 值为 2:
显示的范围 [start_row,start_row + num_rows) 彼此不重叠,代表各自数据帧(DataA、DataB)中的唯一序列/行范围
简而言之,DataA 或 DataB 中的任何行都不会出现在多个范围内。
我想合并 DF,以便获得以下数据框:
row global_index item_id valueA valueB
0 0 x A1 B1
1 0 y A2 B2
2 0 z A3 NaN
3 1 x A4 B1
4 1 z A5 NaN
5 2 x A4 B3
6 2 y A2 B4
7 2 z A5 NaN
8 3 x A6 B3
9 3 y A7 B4
10 3 z A8 B5
11 4 x A6 B6
12 4 y A7 B7
13 4 z A8 B8
在最终的数据帧中,任何一对 global_index/item_id 永远会有:
要求是如果给定的 global_index/item 只有一个值(例如:valueA 但没有 valueB)作为要使用的缺失值的最后一个值。
最佳答案
首先,您可以创建 'global_index'
列使用函数 pd.cut
:
for df, m in [(df_A, map_A), (df_B, map_B)]:
bins = np.insert(m['num_rows'].cumsum().values, 0, 0) # create bins and add zero at the beginning
df['global_index'] = pd.cut(df['row'], bins=bins, labels=m['global_index'], right=False)
接下来,您可以使用外连接到
merge
两个数据框:df = df_A.merge(df_B, on=['global_index', 'item_id'], how='outer')
最后你可以使用函数
groupby
和 ffill
填充缺失值:for val in ['valueA', 'valueB']:
df[val] = df.groupby('item_id')[val].ffill()
输出:
item_id global_index valueA valueB
0 x 0 A1 B1
1 y 0 A2 B2
2 z 0 A3 NaN
3 x 1 A4 B1
4 z 1 A5 NaN
5 x 3 A6 B1
6 y 3 A7 B2
7 z 3 A8 NaN
8 x 2 A6 B3
9 y 2 A7 B4
10 z 2 A8 B5
11 x 4 A6 B6
12 y 4 A7 B7
13 z 4 A8 B8
关于python - 根据来自其他两个 DataFrame 的索引合并两个 DataFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59777009/