Linda
Linda

Reputation: 321

Split row into multiple rows in pandas

I have a DataFrame with a format like this (simplified)

a  b  43
a  c  22

I would like this to be split up in the following way.

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

Where I have as many rows as the number divides by 20, and then as many rows as the remainder. I have a solution that basically iterates over the rows and fills up a dictionary which can then be converted back to Dataframe but I was wondering if there is a better solution.

Upvotes: 2

Views: 1853

Answers (2)

piRSquared
piRSquared

Reputation: 294526

Setup

Consider the dataframe 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.divmod and np.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

Upvotes: 1

jezrael
jezrael

Reputation: 863611

You can use floor divison with modulo first and then create new DataFrame by constructor with numpy.repeat.

Last need numpy.concatenate with list comprehension for C:

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

Upvotes: 4

Related Questions