我有两个数据帧:
帧A:
OB_ID CA_ID col1 col2 col3
4 4 a b c
4 4 a d b
3 5 c c e
这个数据帧很大,我不确定其中的所有ID。
帧B:
OB_ID CA_ID colZ
1 1 sky
4 4 fire
4 3 data
我只想在OB_ID和CA_ID匹配的情况下将colZ添加到帧A,否则在该帧中添加Nan/NUll,结果数据帧如下所示:
OB_ID CA_ID col1 col2 col3 colz
4 4 a b c fire
4 4 a d b fire
3 5 c c e NA/unknown
帧A的形状是8666515行×3列,B的形状是367469行×342列,但当我进行时
df3 = pd.merge(frameA, frameB, on=['OB_ID','CA_ID'], how='left')
df3.shape
它给出了形状:1490420 rows × 343 columns
,但我不明白为什么行数从367469增长到1490420。
左合并后得到的行数大于左数据帧的行数,因为on
部分中的非唯一条目,即左帧的["OB_ID", "CA_ID"]
列,以及Panda如何尝试对齐。例如,帧A具有两次[4, 4]
对。如果帧B有3次,则对齐过程规定合并后的结果帧将有2 x 3=6个[4, 4]
行,即取叉积。(注意:我希望示例[4, 4]
不会混淆:4在那里重复两次是而不是;[4, 4]
作为对/行重复两次。(
这是一个引起大熊猫共鸣的主题:
>>> pd.Series([12, 3], index=[0, 0]) + pd.Series([40, 50, 60], index=[0, 0, 0])
你对这个指数有什么看法;求和结果的大小?是的,它是2 x 3=6个零。
回到问题上来。。。我们可以map
frameA的相关列值,而不是合并,对吧?并且CCD_ 9将被frameB稍微修改:Series是一种字典(映射(;键";以及";值";,好吧,对应的值。因此,我们将["OB_ID", "CA_ID"]
作为索引,"colZ"
作为值;这将产生CCD_ 12。问题是,我们不能直接映射df[["OB_ID", "CA_ID"]]
。。。因为DataFrame不能直接映射。但是MultiIndex是!所以我们开始了:
common_cols = ["OB_ID", "CA_ID"]
target_col = "colZ"
mapper = frame_B.set_index(common_cols )[target_col]
frame_A[target_col] = pd.MultiIndex.from_frame(frame_A[common_cols]).map(mapper)
获取
>>> frame_A
OB_ID CA_ID col1 col2 col3 colZ
0 4 4 a b c fire
1 4 4 a d b fire
2 3 5 c c e NaN
示例数据帧:
frame_A = pd.DataFrame({
'OB_ID': [4, 4, 3],
'CA_ID': [4, 4, 5],
'col1': ['a', 'a', 'c'],
'col2': ['b', 'd', 'c'],
'col3': ['c', 'b', 'e']
})
frame_B = pd.DataFrame({
'OB_ID': [3, 3, 4],
'CA_ID': [5, 5, 6],
'colZ': ['sky', 'air', 'stone']
})
common_cols = ['OB_ID','CA_ID']
当前行为
(只是为了更好地理解而将其可视化(
注意(正如@MustafaAydın所解释的(,len(frame_A)
==3。但由于['OB_ID', 'CA_ID']
的对[3, 5]
在frame_B
中重复两次,合并时使用两次,结果的长度变为4:
pd.merge(frame_A, frame_B, on=common_cols, how='left')
0 | 4 | a | b | >c | nan |
1 | 2 | 3 |