2017-07-03 134 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