簡體   English   中英

有條件地將一個 Pandas dataframe 的列插入另一個 dataframe 的列

[英]Conditionally insert columns of one Pandas dataframe into columns of another dataframe

我有2個數據框:

dfA = pd.DataFrame({'label':[1,5,2,4,2,3],
                    'group':['A']*3 + ['B']*3,
                    'x':[np.nan]*3 + [1,2,3],
                    'y':[np.nan]*3 + [1,2,3]})

dfB = pd.DataFrame({'uniqid':[1,2,3,4,5,6,7],
                    'horizontal':[34,41,23,34,23,43,22],
                    'vertical':[98,67,19,57,68,88,77]})

...看起來像:

   label group    x    y
0      1     A  NaN  NaN
1      5     A  NaN  NaN
2      2     A  NaN  NaN
3      4     B  1.0  1.0
4      2     B  2.0  2.0
5      3     B  3.0  3.0


   uniqid  horizontal  vertical
0       1          34        98
1       2          41        67
2       3          23        19
3       4          34        57
4       5          23        68
5       6          43        88
6       7          22        77

基本上,dfB 包含所有唯一 ID 的“水平”和“垂直”值。 我想用 dfB 中的“水平”和“垂直”值填充 dfA 中的“x”和“y”列,但僅適用於 A 組; B組的數據應保持不變。

所需的 output 將是:

   label group    x    y
0      1     A 34.0 98.0
1      5     A 23.0 68.0
2      2     A 41.0 67.0
3      4     B  1.0  1.0
4      2     B  2.0  2.0
5      3     B  3.0  3.0

我已經使用 .merge() 為 A 組和 B 組向 dataframe 添加了其他列,然后僅將數據復制到 A 組的 x 和 y 列。 最后從 dfB 中刪除列。

dfA = dfA.merge(dfB, how = 'left', left_on = 'label', right_on = 'uniqid')

dfA.loc[dfA['group'] == 'A','x'] = dfA.loc[dfA['group'] == 'A','horizontal'] 
dfA.loc[dfA['group'] == 'A','y'] = dfA.loc[dfA['group'] == 'A','vertical'] 

dfA = dfA[['label','group','x','y']]

產生正確的 output:

   label group     x     y
0      1     A  34.0  98.0
1      5     A  23.0  68.0
2      2     A  41.0  67.0
3      4     B   1.0   1.0
4      2     B   2.0   2.0
5      3     B   3.0   3.0

...但這是一個非常非常丑陋的解決方案。 有更好的解決方案嗎?

combine_first

dfA.set_index(['label', 'group']).combine_first(
    dfB.set_axis(['label', 'x', 'y'], axis=1).set_index(['label'])
).reset_index()

   label group     x     y
0      1     A  34.0  98.0
1      5     A  23.0  68.0
2      2     A  41.0  67.0
3      4     B   1.0   1.0
4      2     B   2.0   2.0
5      3     B   3.0   3.0

fillna

也可以

dfA.set_index(['label', 'group']).fillna(
    dfB.set_axis(['label', 'x', 'y'], axis=1).set_index(['label'])
).reset_index()

我們可以嘗試loc僅提取/更新我們想要的部分。 而且由於您要合並一列,該列在dfB上也具有唯一值,因此您可以使用set_indexloc/reindex

mask = dfA['group']=='A'
dfA.loc[ mask, ['x','y']] = (dfB.set_index('uniqid')
                                .loc[dfA.loc[mask,'label'],
                                     ['horizontal','vertical']]
                                .values
                            )

Output:

   label group     x     y
0      1     A  34.0  98.0
1      5     A  23.0  68.0
2      2     A  41.0  67.0
3      4     B   1.0   1.0
4      2     B   2.0   2.0
5      3     B   3.0   3.0

請注意,如果某些dfA.label不在dfB.uniqueid中,則上述操作將失敗。 在這種情況下,我們需要使用reindex

(dfB.set_index('uniqid')
    .reindex[dfA.loc[mask,'label']
    [['horizontal','vertical']].values
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM