Pandas - Return first item in dataframe, grouped by user
pandas, python
Solution
Here's a hack:
In [75]: def nth_order(x, n):
....: xn = x[:n]
....: return xn.join(Series(arange(len(xn)), name='order', index=xn.index))
....:
In [76]: df.groupby('user_id').apply(lambda x: nth_order(x, 2))
Out[76]:
item_id time user_id order
user_id
1 0 b 0 1 0
2 a 2 1 1
2 1 b 1 2 0
3 4 a 4 3 0
Note that you can't just use `n`, because you may have a group where `len(group) < 2`, therefore
`len(x[:n]) != n`
in every case (as per your question).
This is a feature of this particular kind of slicing in pandas: if you slice pass the end here you'll just get every row (and there may not be `n` rows), whereas with `iloc` indexing, that isn't true. That is, an exception will be raised if you try to slice past the end of the array.
Problem
I have a lot of user/item/timestamp data. I want to know which items were consumed first, second third, etc. by all users. My questions are: if I have a dataframe that is already sorted by time (descending), will it stay sorted by default through the `groupby` process? and, how can I pull out the first two items consumed by any user, even if the user has not consumed two items? ``` import pandas as pd df = pd.DataFrame({'item_id': ['b', 'b', 'a', 'c', 'a', 'b'], 'user_id': [1,2,1,1,3,1], 'time': range(6)}) print df pd.get_dummies(df['item_id']) gp = df.groupby('user_id').head() print gp # Return item_id of first one installed in each case ?? ``` This gives: ``` item_id time user_id 0 b 0 1 1 b 1 2 2 a 2 1 3 c 3 1 4 a 4 3 5 b 5 1 item_id time user_id user_id 1 0 b 0 1 2 a 2 1 3 c 3 1 5 b 5 1 2 1 b 1 2 3 4 a 4 3 ``` Now, I need to pull out the top two item_id values, something like this (but retaining the user_id column is not essential): ``` user_id order item_id 1 0 b 1 1 a 2 0 b 3 0 a ```