获取仅包含每个用户的最新行的新数据帧

时间:2018-02-28 09:43:13

标签: python-3.x pandas dask

我有一个像这样的大数据框:

Id last_item_bought time
'user1' 'bike'  2018-01-01
'user3' 'spoon' 2018-01-01
'user2' 'car'   2018-01-01
'user1' 'spoon' 2018-01-02
'user2' 'bike'  2018-01-02
'user3' 'paper' 2018-01-03

每个用户每天都有0行或1行。

我想要一个具有唯一用户的Dataframe和最新的latest_bought条目:

Id last_item_bought time   
'user1' 'spoon' 
'user2' 'bike'  
'user3' 'paper'

数据以每天的方式保存在文件中,这使我有两个可能的起点:

  1. 将所有数据加载到dask数组中,然后以某种方式过滤掉具有较新条目的用户的行。
  2. 循环从最新到最旧的日子,将每天加载到pandas Dataframe中,并以某种方式将用户添加到新数据框中,这些数据框没有更新的条目(新数据框中已有)。
  3. 我正在寻找性能良好的解决方案。每天可以有几千行,我必须检查几周。

1 个答案:

答案 0 :(得分:2)

我认为您需要sort_values + drop_duplicates

df = df.sort_values(['Id','time']).drop_duplicates('Id', keep='last')
print (df)
        Id last_item_bought        time
3  'user1'          'spoon'  2018-01-02
4  'user2'           'bike'  2018-01-02
5  'user3'          'paper'  2018-01-03

如果需要过滤器输出列:

df = df.sort_values(['Id','time']).drop_duplicates('Id', keep='last').drop('time', axis=1)
print (df)
        Id last_item_bought
3  'user1'          'spoon'
4  'user2'           'bike'
5  'user3'          'paper'

Dask解决方案(用于排序set_index):

df = pd.DataFrame({'Id': ['user1', 'user3', 'user2', 'user1', 'user2', 'user3'],
                   'time': ['2018-01-01', '2018-01-01', '2018-01-01', 
                            '2018-01-02', '2018-01-02', '2018-01-03'], 
                  'last_item_bought': ['bike', 'spoon', 'car', 'spoon', 'bike', 'paper']})
df['time'] = pd.to_datetime(df['time'])
print (df)
      Id last_item_bought       time
0  user1             bike 2018-01-01
1  user3            spoon 2018-01-01
2  user2              car 2018-01-01
3  user1            spoon 2018-01-02
4  user2             bike 2018-01-02
5  user3            paper 2018-01-03

from dask import dataframe as dd 
ddf = dd.from_pandas(df, npartitions=3)

ddf1 = (ddf.set_index('time')
          .drop_duplicates(subset=['Id'], keep='last')
          .set_index('Id')
          .reset_index()
          .compute())
print (ddf1)
      Id last_item_bought
0  user1            spoon
1  user2             bike
2  user3            paper