【问题标题】:concatenate row values for the same index in pandas连接熊猫中同一索引的行值
【发布时间】:2015-07-06 19:15:40
【问题描述】:

我的初始 DataFrame 如下所示:

   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”乘以“数量”:

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

目前我正在使用 groupby() 然后 apply():

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')

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

【问题讨论】:

  • +1 回答一个有趣的问题。看看this。我认为它是相似的。

标签: python pandas


【解决方案1】:

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

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 的回答中获得灵感后确定:

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

这也有效:

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

【讨论】:

  • 这可行,但 df 与我们找到它的方式不同,我认为这并不理想。
  • @LondonRob 对不起,你是什么意思,你的意思是我添加了一个中间列吗?中间步骤是必要的,因为我不知道如何让 applylambda 不尝试扩展列表并保持一维
  • 是的,这就是我的意思(这正是我现在正在努力解决的问题!必须有一个聪明的方法!)
  • @LondonRob 这里的问题是我用看似明智的方式搞砸了结果:df.groupby('A').apply(lambda x: list(x['B'] * x['quantity'])) df.groupby('A').apply(lambda x: ','.join(x['B'] * x['quantity']) )
  • @LondonRob 如果我尝试df.groupby('A').apply(lambda x: ','.join([x['B']] * x['quantity'])) 我会得到Exception: Data must be 1-dimensional 所以我正在为此绞尽脑汁
【解决方案2】:

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

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

【讨论】:

  • 我使用np.repeat 解决了我的groupby 方法;-)
  • @EdChum 同意你的回答。 pivot_table 不需要重塑。 groupby 是一种更简洁的方法。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
相关资源
最近更新 更多