基于列重复DataFrame中的行

时间:2018-05-25 04:47:58

标签: python pandas dataframe

我现在有一个数据框:

   class1  class2  value  value2
0       1       0      1       4
1       2       1      2       3
2       2       0      3       5
3       3       1      4       6

我想重复行并根据valuevalue2之间的差异插入相同数量的增量列。我希望数据框应该是这样的:

    class1  class2  value  value2  value3
0        1       0      1       4       1
1        1       0      1       4       2
2        1       0      1       4       3
3        1       0      1       4       4
4        2       1      2       3       2
5        2       1      2       3       3
6        2       0      3       5       3
7        2       0      3       5       4
8        2       0      3       5       5
9        3       1      4       6       4
10       3       1      4       6       5
11       3       1      4       6       6

我尝试过:

def func(x):
    copy = x.copy()
    num = x.value2+1-x.value
    return pd.concat([copy]*num.values[0])
df= df.groupby(['class1','class2']).apply(lambda x:func(x))

但是会有一个ortr问题导致我不知道如何添加列value3。而且我希望有一种优雅的方式来做到这一点。

任何人都可以帮助我吗?提前致谢

2 个答案:

答案 0 :(得分:2)

计算差异并致电Index.repeat

idx = df.index.repeat(df.value2 - df.value + 1)

现在,使用reindex

df = df.reindex(idx).reset_index(drop=True)

loc

df = df.loc[idx].reset_index(drop=True)

你得到了

df
    class1  class2  value  value2
0        1       0      1       4
1        1       0      1       4
2        1       0      1       4
3        1       0      1       4
4        2       1      2       3
5        2       1      2       3
6        2       0      3       5
7        2       0      3       5
8        2       0      3       5
9        3       1      4       6
10       3       1      4       6
11       3       1      4       6

对于问题的第二部分,您需要groupby.cumcount

s = idx.to_series()
df['value3'] =  df['value'] + s.groupby(idx).cumcount().values
df
    class1  class2  value  value2  value3
0        1       0      1       4       1
1        1       0      1       4       2
2        1       0      1       4       3
3        1       0      1       4       4
4        2       1      2       3       2
5        2       1      2       3       3
6        2       0      3       5       3
7        2       0      3       5       4
8        2       0      3       5       5
9        3       1      4       6       4
10       3       1      4       6       5
11       3       1      4       6       6

答案 1 :(得分:1)

以下是一系列可以获得所需输出的内容:

df.join(df
        .apply(lambda x: pd.Series(range(x.value, x.value2+1)), axis=1)
        .stack().astype(int)
        .reset_index(level=1, drop=1)
        .to_frame('value3')).reset_index(drop=1)

Out[]:
    class1  class2  value  value2  value3
0        1       0      1       4       1
1        1       0      1       4       2
2        1       0      1       4       3
3        1       0      1       4       4
4        2       1      2       3       2
5        2       1      2       3       3
6        2       0      3       5       3
7        2       0      3       5       4
8        2       0      3       5       5
9        3       1      4       6       4
10       3       1      4       6       5
11       3       1      4       6       6