1

有没有更好的方法来做下面的代码在(慢!)循环中所做的事情?

使用输入 DataFrame,我想将其转换为每个用户消费过的产品列表。但是这个列表将长达数百万,这似乎非常低效(除非我使用 cython)。有什么想法可以让这更加python-happy吗?谢谢!

a = pd.DataFrame({'user_id':['a', 'a', 'b', 'c', 'c', 'c'], 'prod_id':['p1', 'p2', 'p1', 'p2', 'p3', 'p7']})

print "Input Dataframe:\n", a
print '\nDesired Output:'

# Build desired output:
uniqIDs = a.user_id.unique()

for id in uniqIDs:

    prod_list = list(a[a.user_id == id].prod_id.values)        

    s = id + '\t'
    for x in prod_list:
        s += x + '\t'

    print s # This will get saved to a TAB DELIMITED file

给出这个输出(这正是我想要的):

Input Dataframe:
  prod_id user_id
0      p1       a
1      p2       a
2      p1       b
3      p2       c
4      p3       c
5      p7       c

Desired Output:
a   p1  p2  
b   p1  
c   p2  p3  p7
4

1 回答 1

3

你可以使用groupby

>>> a = pd.DataFrame({'user_id':['a', 'a', 'b', 'c', 'c', 'c'], 'prod_id':['p1', 'p2', 'p1', 'p2', 'p3', 'p7']})
>>> a
  prod_id user_id
0      p1       a
1      p2       a
2      p1       b
3      p2       c
4      p3       c
5      p7       c
>>> a.groupby("user_id")["prod_id"].unique()
user_id
a              [p1, p2]
b                  [p1]
c          [p2, p3, p7]
dtype: object

唔。

以您想要的确切格式获取输出非常麻烦,因为我看不到任何方法可以覆盖pandas'逃避事物的愿望。IOW,手动生成结果系列很容易.apply('\t'.join),但也很难将其保存\t为分隔符。

所以这是另一种方法:

>>> df = pd.DataFrame({k: g.reset_index(drop=True) 
                       for k,g in a.groupby("user_id")["prod_id"]}).T
>>> df.to_csv("prod.csv", sep="\t", header=False)
>>> !cat prod.csv
a   p1  p2  
b   p1      
c   p2  p3  p7

如果你真的想要,你可以在最后去掉额外的标签。

于 2013-10-10T19:20:14.897 回答