2015-09-01 72 views
0

我有兩個dataframes,就像這樣:從兩個dataframes比較列時,值不完全匹配

In [2]: df1 = pd.DataFrame({'item': ['foo', 'foo', 'bar', 'bar', 'bar', 'qux', 'baz'], 
    ...:      'name': ['apple', 'bird', 'apple', 'bird', 'car', 'car', 'bird'], 
    ...:      'value': [999, 1103, 1070, 1210, 1521, 1622, 1550]}) 

In [3]: df1 
Out[3]: 
    item name value 
0 foo apple 999 
1 foo bird 1103 
2 bar apple 1070 
3 bar bird 1210 
4 bar car 1521 
5 qux car 1622 
6 baz bird 1550 

In [4]: df2 = pd.DataFrame({'item': ['foo', 'foo', 'bar', 'qux'], 
    ...:      'size': [1076, 1266, 1380, 1620], 
    ...:      'total': [5, 10, 5, 13]}) 

In [5]: df2 
Out[5]: 
    item size total 
0 foo 1076  5 
1 foo 1266  10 
2 bar 1380  5 
3 qux 1620  13 

我想檢查df2.size,將其比作df1.value,然後將相應的df1.name添加到df2。

踢球者是df1.valuedf2.size很少精確匹配;相反,我想要最接近的df1.value以下的比(或等於)df2.size的值。換句話說,在上面的df1中,在「foo」項目組中,999和1102之間的任何值都是「apple」組的一部分,超過1103的任何值都將成爲「bird」組的一部分。

另外,item需要在數據幀之間進行匹配。換句話說,被分類爲「foo」item的df2中的size條目應僅與df1中的「foo」進行比較。

我期望的輸出是一樣的東西:

item name size total 
0 foo apple 1076  5 
1 foo bird 1266  10 
2 bar bird 1380  5 
3 qux NaN 1620  13 

有沒有人對我怎麼可能會解決這個問題的任何想法?

一種方法我可以採取將pd.concat的dataframes,然後排序上['item', 'value'],然後ffillname列,然後篩選其中size不爲空。但問題是,在某些情況下,我會向前填充item組,這將導致虛假結果。

+0

這是一個簡單的表上的項目加入了一些篩選,排序和更多的過濾? – Paul

+0

這就是我在我最後一段中提到的 - 實際上,這可能是這樣做的最好方法。儘管如此,我還是希望能有一些熊貓魔術可以幫助解決這個問題。 – dagrha

回答

0

好吧,我還沒有在更大範圍內對此進行測試,但是Paul的建議我已經完成了我試圖在我提供的樣本數據集上實現的目標。

第一步是重命名df2.sizevalue只是爲了簡化pd.concat

df2.rename(columns={'size':'value'}, inplace=True) 

然後級聯這些dataframes,並且通過項目和值排序的新的幀:

df3 = pd.concat([df1, df2], axis=0).sort(['item', 'value']) 

下一個步驟是用正向填充的groupby系列替換df3.name列:

df3['name'] = df3.groupby(['item'])['name'].ffill() 

最後一個步驟是過濾掉其中df3.total是空行:

df3[pd.notnull(df3.total)] 
+0

這個解決方案確實有效(雖然承認它略顯笨拙),所以它看起來像「答案」部分是它應該去的地方。如果別人有更好的方法,但我仍然喜歡聽到它! – dagrha