【问题标题】:Populate one dataframe based on group values from another根据另一个数据框的组值填充一个数据框
【发布时间】:2020-06-08 13:45:17
【问题描述】:

我有一个数据框数据

   groupId service local
0        1      s1    l1
1        1      s1    l1
2        1      s2    l2
3        1      s3    l3
4        2      s2    l2
5        2      s3    l3
6        3      s1    l1
7        3      s2    l2

我有一个数据框问题

   q1  q2  howManyGroups
0  s1  l1              0
1  s1  s2              0
2  s2  l2              0
3  s3  l3              0
4  s3  l1              0

我想根据 data 中出现的组数来计算 question 行的出现次数:

   q1  q2  howManyGroups
0  s1  l1              2
1  s1  s2              2
2  s2  l2              3
3  s3  l3              2
4  s3  l1              1

我正在使用这段代码,但它真的很慢:

for i,g in data.groupby('groupId'):
  for j,r in question.iterrows():
    if set(r[['q1','q2']].values).issubset(set( g.drop('groupId', axis=1).values.ravel())):
      question.loc[j,'howManyGroups'] += 1

编辑:我的问题数据框有时可能比q1 and q2 有更多/更少的列。有时它只有q1,有时它只有q1, q2, q3...

【问题讨论】:

  • 输出没有意义,样本s3,l1中没有组合data
  • 在第 1 组我们有 s1 l1 s1 l1 s2 l2 s3 l3 所以第 1 组的值是 s3,l1,即使它们不在同一行 @quang-hoang
  • @LuizFernandoPuttowSouthier 您的数据框的实际大小是多少?
  • data 大约有 100000 行,问题在 10000 行 @Ben 附近。 T

标签: python numpy dataframe


【解决方案1】:

您可以做的是首先重塑数据以获取每个 groupId 的行和任何列服务或本地中的唯一值。

data_ = (data.set_index('groupId').stack()
             .reset_index(name='h')
             [['groupId', 'h']].drop_duplicates()
        )
print (data_.head())
   groupId   h
0        1  s1
1        1  l1
4        1  s2
5        1  l2
6        1  s3

然后使用 question 和 merge 两次,第一次只在 q1(和 data_ 中的 h)上获取与 q1 关联的 groupId,第二次在 q2 和 groupId 上确保 q1 和 q2 都是在同一组。最后,groupby 在合并之前使用 reset_index 保留的原始索引并在 groupId 上使用 nunique

question['howManyGroups'] = (question[['q1','q2']].reset_index()
                                .merge(data_, left_on=['q1'], right_on=['h'])
                                .merge(data_, left_on=['q2','groupId'], 
                                              right_on=['h','groupId'])
                                .groupby('index')['groupId'].nunique()
                            )
print (question)
   q1  q2  howManyGroups
0  s1  l1              2
1  s1  s2              2
2  s2  l2              3
3  s3  l3              2
4  s3  l1              1

如果你的气数不知道,你可以试试:

df_tmp = (question.reset_index()
                  .merge(data_, left_on=['q1'], right_on=['h'])
         )

l_q = question.filter(regex='q\d*').columns.tolist()
l_q.remove('q1')

for q in l_q:
    df_tmp = df_tmp.merge(data_, left_on=[q,'groupId'], right_on=['h', 'groupId'])

question['howManyGroups'] = df_tmp.groupby('index')['groupId'].nunique()

【讨论】:

  • 如果我的“问题”数据框有可变数量的 q 怎么办:q1, q2 ... qn
  • @LuizFernandoPuttowSouthier 你可以尝试链接merges,但我怀疑效率,我会考虑一下
  • 您能否提供合并链式解决方案@Ben。 T?
  • @LuizFernandoPuttowSouthier 看到编辑,这是我能想到的最好的原始方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
相关资源
最近更新 更多