2016-03-03 98 views
0

我試圖通過另一個DataFrame的值過濾一個DataFrame,但無法使其工作,因爲通過DataFrame的過濾器的大小與要過濾的DataFrame的大小不同。我認爲我需要使用​​以某種方式對齊兩個數據幀,但這可能是錯誤的。比較不同長度的數據框

import pandas as pd 
df1 = pd.DataFrame({'a': [1, 1, 2, 3, 3, 4], 'b': [5, 3, 6, 2, 6, 4]}) 
df2 = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [3, 5, 6, 3]}) 
dfa = df1.set_index('a') 
>>> dfa 
    b 
a 
1 5 
1 3 
2 6 
3 2 
3 6 
4 4 

dfb = df2.set_index('a') 

>>> dfa[dfa['b'] <= dfb['b']] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/core/ops.py", line 699, in wrapper 
    raise ValueError('Series lengths must match to compare') 
ValueError: Series lengths must match to compare 

預期數據幀將是pd.DataFrame({'a': [1, 3, 3], 'b': [3, 2, 6]})

a b 
0 1 3 
1 3 2 
2 3 6 

(所有<a, b>行從df1爲其在df2b值爲<消失=在df1b值和兩個a值匹配df1df2)。

更新

更幼稚的方式不起作用要麼...

>>> df1[(df1['a'] == df2['a']) & (df1['b'] <= df2['b'])] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/core/ops.py", line 699, in wrapper 
    raise ValueError('Series lengths must match to compare') 
ValueError: Series lengths must match to compare 

回答

2

你可以使用reindex_like你的第二個數據幀allign到df1大小,然後用另外的使用你的嘗試isin方法而不是用df2['a']比較df1['a']

df3 = df2.reindex_like(df1) 

In [93]: df1[(df3['a'].isin(df1['a'])) & (df1['b'] <= df3['b'])] 
Out[93]: 
    a b 
1 1 3 
2 2 6 
3 3 2 
2

這裏有一種方法:

>>> df1[df1.b <= df1.a.map(dfb.b)] 
    a b 
1 1 3 
3 3 2 
4 3 6 

它更容易使用df1dfa因爲你需要map,這不會對指數權工作(僅限於系列)。如果您絕對需要使用dfa而不是dfb,則必須將比較的第二部分更改爲dfa.reset_index().a.map(dfb.b)

0

我認爲最簡單的方法是使用merge並將df2的列轉換爲df1

>>> df2['c'] = df2['b'] 
>>> pd.merge(df1, df2, how='left', on=['a']) 
    a b_x b_y c 
0 1 5 3 3 
1 1 3 3 3 
2 2 6 5 5 
3 3 2 6 6 
4 3 6 6 6 
5 4 4 3 3 

然後只是做df1[df1['b_x'] <= df1['c']]