关于python:在pandas中连接相同索引的行值

concatenate row values for the same index in pandas

我的初始DataFrame如下所示:

1
2
3
4
5
6
7
8
   A    B  quantity
0  1  foo         1
1  1  baz         2
2  1  bar         2
3  1  faz         1
4  2  foo         2
5  2  bar         1
6  3  foo         3

我需要将其按'A'分组,并列出'B'乘以'quantity':

1
2
3
4
   A                               B
0  1  [foo, baz, baz, bar, bar, faz]
1  2                 [foo, foo, bar]
2  3                 [foo, foo, foo]

当前我正在使用groupby(),然后套用apply():

1
2
3
4
5
6
7
8
9
def itemsToList(tdf, column):

    collist = []
    for row in tdf[column].iteritems():
        collist = collist + tdf['quantity'][row[0]]*[row[1]]

    return pd.Series({column: collist})

gb = df.groupby('A').apply(itemsToList, 'B')

我怀疑这是一种有效的方法,所以我正在寻找一种好的"pandas式"方法来实现这一目标。


这可以分两步完成,生成一个新列以创建扩展的str值,然后在'A'上的groupbyapply list到此新列:

1
2
3
4
5
6
7
8
9
10
In [62]:
df['expand'] = df.apply(lambda x: ','.join([x['B']] * x['quantity']), axis=1)
df.groupby('A')['expand'].apply(list)

Out[62]:
A
1    [foo, baz,baz, bar,bar, faz]
2                  [foo,foo, bar]
3                   [foo,foo,foo]
Name: expand, dtype: object

编辑

从@Jianxun Li的答案中汲取灵感后确定:

1
2
3
4
5
6
7
8
9
In [130]:
df.groupby('A').apply(lambda x: np.repeat(x['B'].values, x['quantity']).tolist())

Out[130]:
A
1    [foo, baz, baz, bar, bar, faz]
2                   [foo, foo, bar]
3                   [foo, foo, foo]
dtype: object

这也有效:

1
2
3
4
5
6
7
8
9
In [131]:
df.groupby('A').apply(lambda x: list(np.repeat(x['B'].values, x['quantity'])))

Out[131]:
A
1    [foo, baz, baz, bar, bar, faz]
2                   [foo, foo, bar]
3                   [foo, foo, foo]
dtype: object


另一种方法。首先使用pivot_table重塑df的形状,然后使用apply np.repeat().tolist()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import pandas as pd
import numpy as np

df

Out[52]:
   A    B  quantity
0  1  foo         1
1  1  baz         2
2  1  bar         2
3  1  faz         1
4  2  foo         2
5  2  bar         1
6  3  foo         3

df.pivot('A','B','quantity').fillna(0).apply(lambda row: np.repeat(row.index.values, row.values.astype(int)).tolist(), axis=1)

Out[53]:
A
1    [bar, bar, baz, baz, faz, foo]
2                   [bar, foo, foo]
3                   [foo, foo, foo]
dtype: object