获取每个用户只有最新行的新数据框
Get new dataframe with only the latest rows per user
我有一个大数据框,如下所示:
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 行。
我想要一个具有唯一用户和最新 latest_bought 条目的 Dataframe:
Id last_item_bought time
'user1' 'spoon'
'user2' 'bike'
'user3' 'paper'
数据每天保存在一个文件中,这让我想到了两个可能的起点:
- 将所有数据加载到一个 dask 数组中,然后以某种方式过滤掉具有较新条目的用户的行。
- 从最新到最旧的日子循环,将每一天加载到 pandas Dataframe 并以某种方式仅将用户添加到新的 dataframe,其中没有更新的条目(不在新的 dataframe 中) .
我正在寻找性能良好的解决方案。每天可能有几千行,我必须检查数周。
我认为你需要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
我有一个大数据框,如下所示:
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 行。
我想要一个具有唯一用户和最新 latest_bought 条目的 Dataframe:
Id last_item_bought time
'user1' 'spoon'
'user2' 'bike'
'user3' 'paper'
数据每天保存在一个文件中,这让我想到了两个可能的起点:
- 将所有数据加载到一个 dask 数组中,然后以某种方式过滤掉具有较新条目的用户的行。
- 从最新到最旧的日子循环,将每一天加载到 pandas Dataframe 并以某种方式仅将用户添加到新的 dataframe,其中没有更新的条目(不在新的 dataframe 中) .
我正在寻找性能良好的解决方案。每天可能有几千行,我必须检查数周。
我认为你需要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