Home > front end >  Pandas create dataframe from one row
Pandas create dataframe from one row

Time:09-21

Let us say i have some dataframe df and I want to create a new dataframe new_df with n rows each being the same as row idx from df. Is there a faster way compared to:

import pandas as pd

df = pd.DataFrame()
new_df = pd.DataFrame()


for i in range(n):
    new_df.loc[i] = df.iloc[idx]

thanks

CodePudding user response:

You can use repeat:

N = 5
new_df = df.loc[df.index.repeat(N)]
# or for a particular row idx
new_df = df.loc[df.loc[idx].index.repeat(N)]

Or, for a new index reset_index with drop=True:

new_df = df.loc[df.index.repeat(N)].reset_index(drop=True)
# or for a particular row idx
new_df = df.loc[df.loc[idx].index.repeat(N)].reset_index(drop=True)

NB. if you have many rows in the input and only want to repeat one or some. replace df.index.repeat(N) with df.loc[idx].index.repeat(N) of df.loc[['idx1', 'idx2', 'idx3']].index.repeat(N)

Example input:

df = pd.DataFrame([['A', 'B', 'C']])

Output:

   0  1  2
0  A  B  C
1  A  B  C
2  A  B  C
3  A  B  C
4  A  B  C

CodePudding user response:

Sample:

np.random.seed(100)
df = pd.DataFrame(np.random.randint(10, size=(5,5)), columns=list('ABCDE'))
print (df)
   A  B  C  D  E
0  8  8  3  7  7
1  0  4  2  5  2
2  2  2  1  0  8
3  4  0  9  6  2
4  4  1  5  3  4

You can create dictionary/list by row idx and call DataFrame constructor:

idx = 2
N = 10
df1 = pd.DataFrame(df.loc[idx].to_dict(), index=range(N))
df1 = pd.DataFrame([df.loc[idx].tolist()], index=range(N), columns=df.columns)
print (df1)
   A  B  C  D  E
0  2  2  1  0  8
1  2  2  1  0  8
2  2  2  1  0  8
3  2  2  1  0  8
4  2  2  1  0  8
5  2  2  1  0  8
6  2  2  1  0  8
7  2  2  1  0  8
8  2  2  1  0  8
9  2  2  1  0  8

Another solution with numpy.repeat and DataFrame.loc, for default index use DataFrame.reset_index with drop=True:

idx = 2
N = 10
df1 = df.loc[np.repeat(idx, N)].reset_index(drop=True)
print (df1)
   A  B  C  D  E
0  2  2  1  0  8
1  2  2  1  0  8
2  2  2  1  0  8
3  2  2  1  0  8
4  2  2  1  0  8
5  2  2  1  0  8
6  2  2  1  0  8
7  2  2  1  0  8
8  2  2  1  0  8
9  2  2  1  0  8

Performance comparison (with my data, bset test in your real data):

np.random.seed(100)
df = pd.DataFrame(np.random.randint(10, size=(5,5)), columns=list('ABCDE'))
print (df)

idx = 2
N = 10000

In [260]: %timeit pd.DataFrame([df.loc[idx].tolist()], index=range(N), columns=df.columns)
690 µs ± 44.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [261]: %timeit pd.DataFrame(df.loc[idx].to_dict(), index=range(N))
786 µs ± 106 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [262]: %timeit df.loc[np.repeat(idx, N)].reset_index(drop=True)
796 µs ± 26.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

@mozway solution
In [263]: %timeit df.loc[df.index.repeat(N)].reset_index(drop=True)
3.62 ms ± 178 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

@original solution
In [264]: %%timeit
     ...: nnew_df = pd.DataFrame(columns=df.columns)
     ...: for i in range(N):
     ...:     new_df.loc[i] = df.iloc[idx]
     ...:     
2.44 s ± 274 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
  • Related