查找Pandas Dataframe比较不同大小的数据帧

时间:2017-08-31 12:00:02

标签: python-3.x pandas

我有两只看起来像这样的pandas

df1
   Amount   Price
0    5       50
1    10      53 
2    15      55
3    30      50
4    45      61

df2 
     Used amount
 0      4.5
 1      1.2
 2      6.2
 3      4.1 
 4      25.6
 5      31
 6      19
 7      15  

我试图在df2上插入一个新列,它将提供df1的价格,df1和df2有不同的大小,df1更小

我期待这样的事情

df3 
     Used amount price
 0      4.5       50
 1      1.2       50
 2      6.2       53
 3      4.1       50
 4      25.6      50
 5      31        61
 6      19        50
 7      15        55

我正在考虑用这个函数来解决这个问题

def price_function(key, table):
    used_amount_df2 = (row[0] for row in df1)
    price = filter(lambda x: x < key, used_amount_df1)

4 个答案:

答案 0 :(得分:2)

这是我自己的解决方案

第一种方法:

from itertools import product
import pandas as pd
df2=df2.reset_index()
DF=pd.DataFrame(list(product(df2.Usedamount, df1.Amount)), columns=['l1', 'l2'])
DF['DIFF']=(DF.l1-DF.l2)
DF=DF.loc[DF.DIFF<=0,]
DF=DF.sort_values(['l1','DIFF'],ascending=[True,False]).drop_duplicates(['l1'],keep='first')
df1.merge(DF,left_on='Amount',right_on='l2',how='left').merge(df2,left_on='l1',right_on='Usedamount',how='right').loc[:,['index','Usedamount','Price']].set_index('index').sort_index()


Out[185]: 
       Usedamount  Price
index                   
0             4.5     50
1             1.2     50
2             6.2     53
3             4.1     50
4            25.6     50
5            31.0     61
6            19.0     50
7            15.0     55

第二次使用pd.merge_asof 我建议

df2=df2.rename({'Used amount':Amount}).sort_values('Amount')
df2=df2.reset_index()
  pd.merge_asof(df2,df1,on='Amount',allow_exact_matches=True,direction='forward')\
   .set_index('index').sort_index()

Out[206]: 
       Amount  Price
index               
0         4.5     50
1         1.2     50
2         6.2     53
3         4.1     50
4        25.6     50
5        31.0     61
6        19.0     50
7        15.0     55

答案 1 :(得分:1)

您可以使用cutsearchsorted创建分区。

注意:df1中的索引必须是默认的 - 0,1,2...

#create default index if necessary
df1 = df1.reset_index(drop=True)

#create bins
bins = [0] + df1['Amount'].tolist()
#get index values of df1 by values of Used amount
a = pd.cut(df2['Used amount'], bins=bins, labels=df1.index)
#assign output
df2['price'] = df1['Price'].values[a]
print (df2)
   Used amount  price
0          4.5     50
1          1.2     50
2          6.2     53
3          4.1     50
4         25.6     50
5         31.0     61
6         19.0     50
7         15.0     55
a = df1['Amount'].searchsorted(df2['Used amount'])
df2['price'] = df1['Price'].values[a]
print (df2)
   Used amount  price
0          4.5     50
1          1.2     50
2          6.2     53
3          4.1     50
4         25.6     50
5         31.0     61
6         19.0     50
7         15.0     55

答案 2 :(得分:1)

您可以将pd.DataFrame.reindexmethod=bfill

一起使用
df1.set_index('Amount').reindex(df2['Used amount'], method='bfill')

             Price
Used amount       
4.5             50
1.2             50
6.2             53
4.1             50
25.6            50
31.0            61
19.0            50
15.0            55

要将其添加到新列,我们可以使用

join

df2.join(
    df1.set_index('Amount').reindex(df2['Used amount'], method='bfill'),
    on='Used amount'
)

   Used amount  Price
0          4.5     50
1          1.2     50
2          6.2     53
3          4.1     50
4         25.6     50
5         31.0     61
6         19.0     50
7         15.0     55

assign

df2.assign(
    Price=df1.set_index('Amount').reindex(df2['Used amount'], method='bfill').values)

   Used amount  Price
0          4.5     50
1          1.2     50
2          6.2     53
3          4.1     50
4         25.6     50
5         31.0     61
6         19.0     50
7         15.0     55

答案 3 :(得分:0)

使用pd.IntervalIndex即可

In [468]: df1.index = pd.IntervalIndex.from_arrays(df1.Amount.shift().fillna(0),df1.Amount)

In [469]: df1
Out[469]:
              Amount  Price
(0.0, 5.0]         5     50
(5.0, 10.0]       10     53
(10.0, 15.0]      15     55
(15.0, 30.0]      30     50
(30.0, 45.0]      45     61

In [470]: df2['price'] = df2['Used amount'].map(df1.Price)

In [471]: df2
Out[471]:
   Used amount  price
0          4.5     50
1          1.2     50
2          6.2     53
3          4.1     50
4         25.6     50
5         31.0     61
6         19.0     50
7         15.0     55