2017-07-03 148 views
1

我有一个数据帧,像这样的格式(简体)拆分一行到多行大熊猫

a b 43 
a c 22 

我想这通过以下方式被分拆。

a b 20 
a b 20 
a b 1 
a b 1 
a b 1 
a c 20 
a c 1 
a c 1 

在那里我的行数与数字除以20一样多,然后行数与余数相等。我有一个解决方案,基本上遍历行和填充字典,然后可以转换回数据帧,但我想知道是否有更好的解决方案。

回答

3

您可以首先以模数使用floor divison,然后通过constructornumpy.repeat创建新的DataFrame

最后需要numpy.concatenatelist comprehensionC

a,b = df.C // 20, df.C % 20 
#print (a, b) 

cols = ['A','B'] 
df = pd.DataFrame({x: np.repeat(df[x], a + b) for x in cols}) 
df['C'] = np.concatenate([[20] * x + [1] * y for x,y in zip(a,b)]) 
print (df) 
    A B C 
0 a b 20 
0 a b 20 
0 a b 1 
0 a b 1 
0 a b 1 
1 a c 20 
1 a c 1 
1 a c 1 
+0

我得到一个'ValueError异常:操作数无法与形状(2)一起广播(3810)'就在np.repeat行尝试此。 – Linda

+0

问题与您的样本数据有关吗?或者用真实的数据?在您的真实数据解决方案中,只有数据被更改? – jezrael

+0

问题在于示例数据。当我尝试你的解决方案时,我得到了上述错误。 – Linda

1

设置

考虑数据框df

df = pd.DataFrame(dict(A=['a', 'a'], B=['b', 'c'], C=[43, 22])) 
df 

    A B C 
0 a b 43 
1 a c 22 

np.divmodnp.repeat

m = np.array([20, 1]) 
dm = list(zip(*np.divmod(df.C.values, m[0]))) 
# [(2, 3), (1, 2)] 

rep = [sum(x) for x in dm] 
new = np.concatenate([m.repeat(x) for x in dm]) 

df.loc[df.index.repeat(rep)].assign(C=new) 

    A B C 
0 a b 20 
0 a b 20 
0 a b 1 
0 a b 1 
0 a b 1 
1 a c 20 
1 a c 1 
1 a c 1