簡體   English   中英

熊貓Python更新數據框A的值(如果在數據框B中找到)

[英]Pandas Python updating a value of a dataframe A if it is found in Dataframe B

我有兩個數據框,用戶和設備。 用戶數據框是按user_id和時間戳列出的所有交互的列表。 但是,如果有人使用我們的應用程序作為訪客,則他們的user_id將設置為device_id。 如果這些來賓最終成為成員,我們將在設備數據框中將其user_id映射到其device_id。

所以我們有用戶

user_id                                 timestamp
user13123                               2019-02-17
user224234                              2019-02-17
user32134234                            2019-02-17
00029AD9-X5X5-999N-807F-73F0EAE4A98B    2019-02-17

最后一行是訪客用戶,設備ID存儲為user_id

然后用於設備

device_id                               user_id
00029AD9-X5X5-999N-807F-73F0EAE4A98B    user3423
37029BD9-D5D5-435D-837F-73F0EAE4A98B    user34423
...

這是device_id和已知的user_id之間的簡單映射

因此,我要檢查的是Users.user_id是否與Devices.device_id匹配,如果是,則將Users.user_id設置為Devices.user_id。 基本上,如果我們在設備中擁有此信息,我想更新任何舊的來賓交互以使用user_id。

糾纏了一段時間,它變得越來越混亂,感覺像是可以在大熊貓中很干凈地解決的東西。 任何幫助深表感謝。

謝謝!

Dataframes

In [32]: users
Out[32]:
                                user_id   timestamp
0                             user13123  2019-02-17
1                            user224234  2019-02-17
2                          user32134234  2019-02-17
3  00029AD9-D5D5-435D-807F-73F0EAE4A98B  2019-02-17

In []: devices
Out[]:
                              device_id    user_id
0  00029AD9-D5D5-435D-807F-73F0EAE4A98B   user3423
1  37029BD9-D5D5-435D-837F-73F0EAE4A98B  user34423

計算過濾器

user_iddevice_id匹配的所有用戶

In []: filtr = users.user_id.isin(devices.device_id)

In []: filtr
Out[]:
0    False
1    False
2    False
3     True
Name: user_id, dtype: bool

替代值

在數據幀users所有已過濾用戶的user_iduser_id匹配設備的user_id替換。

In []: users.loc[filtr, "user_id"] = users[filtr].user_id.map(devices.set_index("device_id").user_id)

In []: users
Out[]:
        user_id   timestamp
0     user13123  2019-02-17
1    user224234  2019-02-17
2  user32134234  2019-02-17
3      user3423  2019-02-17

使用np.where

只是另一種變化。

users.loc[:, 'user_id'] = pd.np.where(users.user_id.isin(devices.device_id),
                                      users.user_id.map(devices.set_index('device_id').user_id),
                                      users.user_id)

這些解決方案期望每個device_id僅存在一個user_id

左合並usersdevicesfillna在左連接的列user_id (它的名稱為user_id_y )上。 最后,將其分配回users.user_id

In [59]: users['user_id'] = users.merge(devices, how='left', left_on='user_id', right_on='device_id')['user_id_y'].fillna(users.user_id)

In [60]: users
Out[60]:
    timestamp       user_id
0  2019-02-17     user13123
1  2019-02-17    user224234
2  2019-02-17  user32134234
3  2019-02-17      user3423

這是一個循環,盡管對user_id的所有條目檢查都與device_id匹配,但如果這樣,它將使用正確的ID更新Users數據幀。

for i in range(len(Users.index)):
    for p in range(len(Devices.index)):
        if(Users.loc[i,"user_id"] == Devices.loc[p,"device_id"]):
             # Fixed part of the code, check old version.
             Users.loc[i,"user_id"] = Devices.loc[p,"user_id"]

此解決方案找到匹配ID的列表,然后循環瀏覽一次,並使用它作為索引來更新user_id。

devices = pd.DataFrame({'device_id':{0:'00029AD9-X5X5-999N-807F-73F0EAE4A98B',1:'37029BD9-D5D5-435D-837F-73F0EAE4A98B'},'user_id':{0:'user3423',1:'user34423'}})
users = pd.DataFrame({'user_id':{0:'user13123',1:'user224234',2:'user32134234',3:'00029AD9-X5X5-999N-807F-73F0EAE4A98B'},'timestamp':{0:'2019-02-17',1:'2019-02-17',2:'2019-02-17',3:'2019-02-17'}})

matching_ids = list(set(users.user_id).intersection(set(devices.device_id)))
for id in matching_ids:
    users.loc[users.user_id == id, 'user_id'] = devices.set_index('device_id').at[id, 'user_id']

暫無
暫無

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

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