簡體   English   中英

基於另一個新數據幀更新數據幀

[英]Updating Dataframe based on another new dataframe

我有 2 個數據幀的結構如下:

df1 = pd.read_csv("Main_Database.csv")
# df1 Columns: ..., Timestamp, Name, Query, Website, Status,...

df2 = pd.read_csv("New_Raw_Results.csv")
# df2 COlumns: ..., Timestamp, Name, Query, Website, Status,...

兩個數據框可以具有完全相同的列。

我的Main_database.csv跟蹤所有記錄,我的new_raw_results是每周出現的新結果列表。 我想根據 3 個場景處理我的main_database中的更改:

A) 如果在 DF1 中找到 DF2 中的查詢和網站,--> 在 DF1 列“Last Seen”中寫入,使用來自 Df2 的時間戳 --> 將狀態覆蓋為"STILL ACTIVE"

B) 如果在 DF1 中找不到 DF2 中的查詢和網站,--> 將整個 df2.row 附加到 df1--> 將狀態覆蓋為"NET NEW"

C) 如果在 DF2 中找不到 DF1 中的查詢和網站,--> 將狀態覆蓋為"EXPIRED"

我嘗試使用合並和連接的組合,但我被困在這里。 例如,如果我在新數據框中隔離這兩個表之間的內部連接結果,我不確定如何使用它對我的主數據庫執行操作。 我試圖在一個函數下滿足所有這些條件,所以我可以使用這個函數來處理新條目。

你會如何構建這個函數? 解決這個問題的最簡潔的方法是什么?

數據集

import pandas as pd
from numpy.random import default_rng
rng = default_rng()

columns = ['query','website','timestamp','status','last_seen']
data = rng.integers(1,20,(100,5))
df1 = pd.DataFrame(data=data, columns=columns,dtype=str)
data = rng.integers(1,20,(100,5))
df2 = pd.DataFrame(data=data, columns=columns,dtype=str)

連接querywebsite列將有助於比較。 例如

      Query   Website
  0  query1  website1  --> 'query1website1'

為連接列的每個 DataFrame 制作一個系列

a = df2['query'].str.cat(df2.website)
b = df1['query'].str.cat(df1.website)

為您的三個條件中的每一個創建一個布爾系列。

cond1 = a.isin(b)    # ended up not using this
cond2 = ~cond1
cond3 = ~b.isin(a)

根據條件 3 設置狀態 - 您的C)

df1.loc[cond3,'status'] = 'EXPIRED'

更新新信息 - 你的A)

使用 numpy廣播將所有 df2 值 ( a ) 與所有 df1 值 ( b ) 進行比較,並獲取它們匹配的索引。

indices1 = (a.values[:,None] == b.values).argmax(1)

(a.values[:,None] == b.values)產生一個二(a.values[:,None] == b.values)數組,它是每個a值與每個b值的比較。 argmax函數返回它們匹配的索引。

# df1 row indices where df1.qw == df2.qw
x = indices1[indices1 > 0]
# df2 rows where df2.qw == df1.qw
y = df2.loc[np.where(indices1 > 0)]

x是一個df1整數索引數組,在df2中有匹配項 y是與xdf2的子集)對應的匹配項的數據幀。 使用整數數組將新值分配給正確的df1行。

df1.loc[x,'last_seen'] = y.timestamp.values
df1.loc[x,'status'] = "STILL ACTIVE"

警告:如果 df1 有多行qw具有相同的值, np.argmax 只會找到第一行,而第二行的列保持不變。 使用隨機數據會定期出現。


添加新行 - 你的B)

df2.loc[cond2,'status'] = "NET NEW"
df1 = pd.concat([df1,df2.loc[cond2]], ignore_index=True)

完全的...

a = df2['query'].str.cat(df2.website)
b = df1['query'].str.cat(df1.website)

cond1 = a.isin(b)    # ended up not using this
cond2 = ~cond1
cond3 = ~b.isin(a)

df1.loc[cond3,'status'] = 'EXPIRED'

indices1 = (a.values[:,None] == b.values).argmax(1)
x = indices1[indices1 > 0]
y = df2.loc[np.where(indices1 > 0)]

df1.loc[x,'last_seen'] = y.timestamp.values
df1.loc[x,'status'] = "STILL ACTIVE"

df2.loc[cond2,'status'] = "NET NEW"
df1 = pd.concat([df1,df2.loc[cond2]], ignore_index=True)

這應該做你的事情:

import pandas as pd

data = [
{"timestamp": 1, "last_seen": 1, "status": "XXX", "website": "website1", "query": "query1"},
{"timestamp": 1, "last_seen": 2, "status": "XXX", "website": "website2", "query": "query2"},
{"timestamp": 1, "last_seen": 3, "status": "XXX", "website": "website3", "query": "query1"},
{"timestamp": 1, "last_seen": 4, "status": "XXX", "website": "website5", "query": "query1"},
{"timestamp": 1, "last_seen": 5, "status": "XXX", "website": "website6", "query": "query1"}
]

new_data = [
{"timestamp": 1, "last_seen": 6, "status": "XXX", "website": "website1", "query": "query1"},
{"timestamp": 1, "last_seen": 7, "status": "XXX", "website": "website2", "query": "query2"},
{"timestamp": 1, "last_seen": 8, "status": "XXX", "website": "website3", "query": "query4"},
{"timestamp": 1, "last_seen": 9, "status": "XXX", "website": "website3", "query": "query8"}
]

df = pd.DataFrame(data)
df_new = pd.DataFrame(new_data)

for i, row in df.iterrows():
    tmp = df_new.loc[(df_new['website'] == row['website']) & (df_new['query'] == row['query'])]
    if not tmp.empty:
        # A)
        df.at[i, 'last_seen'] = tmp['last_seen']
        df.at[i, 'status'] = "STILL ACTIVE"
    else:
        # B)
        df.at[i, 'status'] = "EXPIRED"

for i, row in df_new.iterrows():
    # C)
    tmp = df.loc[(df['website'] == row['website']) & (df['query'] == row['query'])]
    if tmp.empty:
        row["status"] = "NET NEW"
        df = df.append(row, ignore_index=True)

print(df)

暫無
暫無

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

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