当尝试修改pandas groupby的列值时,“ValueError:值的长度与索引的长度不匹配”

时间:2017-09-27 11:40:39

标签: python pandas dataframe group-by pandas-groupby

我有一个数据框:

       A         C         D
0    one  0.410599 -0.205158
1    one  0.144044  0.313068
2    one  0.333674 -0.742165
3  three  0.761038 -2.552990
4  three  1.494079  2.269755
5    two  1.454274 -0.854096
6    two  0.121675  0.653619
7    two  0.443863  0.864436

我们假设A是锚列。我现在想要在顶部显示每个组值

        A         C         D
0    one  0.410599 -0.205158
1         0.144044  0.313068
2         0.333674 -0.742165
3  three  0.761038 -2.552990
4         1.494079  2.269755
5    two  1.454274 -0.854096
6         0.121675  0.653619
7         0.443863  0.864436

这就是我想出来的:

df['A'] = df.groupby('A', as_index=False)['A']\
        .apply(lambda x: x.str.replace('.*', '').set_value(0, x.values[0])).values

我的策略是做一个groupby,然后将所有值设置为除第一个之外的空字符串。这似乎不起作用,因为我得到:

ValueError: Length of values does not match length of index

这意味着我得到的输出不正确。任何想法/建议/改进欢迎。

我应该补充一点,我正在尝试推广一个可以在每个组的顶部或底部或中间单独输出值的解决方案,因此我会更倾向于帮助我做到这一点的解决方案(理解,上面的示例显示了如何仅在每个组的顶部单独输出值 ,但是,我想概括一个允许我在底部或中间单独输出的解决方案。

2 个答案:

答案 0 :(得分:2)

由于索引错误,您的方法无效。当您对“A”进行分组时,索引在分组数据中的表示方式也相同。由于set_value(0)无法找到正确的索引,因此会使用该索引创建新对象。这就是为什么长度不匹配的原因。

修复1
reset_index(drop=True)

df['A'] = df.groupby('A')['A'].apply(lambda x: x.str.replace('.*', '')\
                      .reset_index(drop=True).set_value(0, x.values[0])).values
df

      A         C         D
0    one  0.410599 -0.205158
1         0.144044  0.313068
2         0.333674 -0.742165
3  three  0.761038 -2.552990
4         1.494079  2.269755
5    two  1.454274 -0.854096
6         0.121675  0.653619
7         0.443863  0.864436

修复2
set_value

set_value有一个名为takeable的第三个参数,用于确定索引的处理方式。默认情况下为False,但将其设置为True适用于我的情况。

除了Zero's solutions之外,在其组中心隔离值的解决方案如下:

df.A = df.groupby('A'['A'].apply(lambda x: x.str.replace('.*', '')\
                           .set_value(len(x) // 2, x.values[0], True)).values 

df

       A         C         D
0         0.410599 -0.205158
1    one  0.144044  0.313068
2         0.333674 -0.742165
3         0.761038 -2.552990
4  three  1.494079  2.269755
5         1.454274 -0.854096
6    two  0.121675  0.653619
7         0.443863  0.864436

答案 1 :(得分:1)

由于值已排序,因此对第一个和最后一个案例使用duplicated方法。

保持第一

In [4233]: df.loc[df.A.duplicated(keep='first'), 'A'] = ''

In [4234]: df
Out[4234]:
       A         C         D
0    one  0.410599 -0.205158
1         0.144044  0.313068
2         0.333674 -0.742165
3  three  0.761038 -2.552990
4         1.494079  2.269755
5    two  1.454274 -0.854096
6         0.121675  0.653619
7         0.443863  0.864436

保持最后

In [4236]: df.loc[df.A.duplicated(keep='last'), 'A'] = ''

In [4237]: df
Out[4237]:
       A         C         D
0         0.410599 -0.205158
1         0.144044  0.313068
2    one  0.333674 -0.742165
3         0.761038 -2.552990
4  three  1.494079  2.269755
5         1.454274 -0.854096
6         0.121675  0.653619
7    two  0.443863  0.864436