編輯:更新了預期的輸出和解釋
我有一個表 'Table1' 為:
Fruit Site Feature1 Feature2 Feature3
Apple Sydney A1 B1 C1
Banana Sydney A1 B1 C1
Cherry Sydney A1 B2 C1
Durian Melbourne A1 B1 C2
Grape Melbourne A2 B2 C2
另一個表,'Table2' 為:
Order Site Feature1 Feature2 Feature3
XX Sydney A2 B1 C1
XY Sydney A1 B1 C1
XZ Sydney A1 B1 C2
YY Melbourne A1 B1 C1
YZ Melbourne A1 B1 C1
ZZ Melbourne A2 B1 C1
表 2 的行比表 1 多。功能和訂單具有文本值。
我正在嘗試執行以下操作:
對于同一地點的每個水果,找到 中匹配次數最多的順序Feature1,Feature2,Feature3。在這里,高匹配數是(例如)所有三個特征的相同值。如果只有兩個特征只有相同的值,則匹配度較低。
因此,從第一個水果開始,搜索匹配次數最多的訂單(在同一站點),然后轉到下一個水果,只查找第一次匹配后剩下的訂單。
預期產出
Fruit Order Matches
Apple XY 3
Banana XX 2
Cherry XZ 1
Durian YY 2
Grape ZZ 1
Apple 有 Order XY,因為它有最多的匹配項。由于訂單 XY 已經匹配,香蕉的最佳匹配是訂單 XX。即使訂單 XX 和 XZ 與 Banana 的匹配次數相同,但優先考慮較早的順序。例如,榴蓮被匹配到訂單 YY 而不是訂單 YZ,即使它們具有相同數量的匹配。
如果水果沒有匹配項,則不會將其包含在輸出中。
我的計劃是在站點上使用合并,因此我們會在同一站點看到所有水果訂單,然后選擇匹配度最高的訂單。但是,我不知道如何確保匹配的訂單不會出現在其余水果中。
我該如何解決這個問題?
uj5u.com熱心網友回復:
這是melt在merge兩個資料幀之前作為起點的完美用例。melt平整您的值列 ( FeatureX)。合并后,您需要比較兩列values_x(來自 df1 的特征)和values_y(來自 df2 的特征)。
現在,使用query,保留這 2 列相等的行。然后,value_counts在(Fruit, Order)列上使用,然后使用rename和重新格式化資料框reset_index。最后,drop_duplicates在Fruit列上保留第一個計數,最高值,因為該Matches列已經排序。
可以一步步執行這個單行,看看dataframe的變換:
out = pd.merge(df1.melt(['Fruit', 'Site']),
df2.melt(['Order', 'Site']),
on=['Site', 'variable']) \
.query('value_x == value_y') \
.value_counts(['Fruit', 'Order']) \
.rename('Matches') \
.reset_index() \
.drop_duplicates('Fruit')
最終輸出:
>>> out
Fruit Order Matches
0 Apple XY 3
1 Banana XY 3
6 Cherry XY 2
7 Durian YY 2
12 Grape ZZ 1
注意:仔細檢查我的結果,因為它不等于你的輸出。
uj5u.com熱心網友回復:
您可以這樣做的一種方法是通過將“水果”和“站點”設定為索引,然后找到每行中唯一值的數量來分組
>>> import pandas as pd
>>> df = pd.DataFrame(
... {
... "Fruit": ["Apple", "Banana", "Grape"],
... "Site": ["Sydney", "Melbourne", "Melbourne"],
... "Feature1": [1, 2, 3],
... "Feature2": [1, 1, 1],
... "Feature3": [1, 3, 3],
... }
... )
>>>
>>> df = df.set_index(['Fruit', 'Site'])
>>>
>>> df.loc[df.nunique(axis=1) == 1, 'Order'] = 1
>>> df.loc[df.nunique(axis=1) > 1, 'Order'] = 2
>>>
>>> df
Feature1 Feature2 Feature3 Order
Fruit Site
Apple Sydney 1 1 1 1.0
Banana Melbourne 2 1 3 2.0
Grape Melbourne 3 1 3 2.0
>>>
>>> # If you just want the counts
>>>
>>> df['Order2'] = df.nunique(axis=1)
>>> df
Feature1 Feature2 Feature3 Order Order2
Fruit Site
Apple Sydney 1 1 1 1.0 1
Banana Melbourne 2 1 3 2.0 3
Grape Melbourne 3 1 3 2.0 3
更新:
在我提供此答案后,您更改了問題。你的問題現在完全不同了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/369031.html
下一篇:比較兩個資料框列并添加匹配值
