Dick Eshelman
Dick Eshelman

Reputation: 1143

Pandas, concat Series to DF as rows

I attempting to add a Series to an empty DataFrame and can not find an answer either in the Doc's or other questions. Since you can append two DataFrames by row or by column it would seem there must be an "axis marker" missing from a Series. Can anyone explain why this does not work?.

import Pandas as pd
df1 = pd.DataFrame()
s1 = pd.Series(['a',5,6])
df1 = pd.concat([df1,s1],axis = 1)
#go run some process return s2, s3, sn ...
s2 = pd.Series(['b',8,9])
df1 = pd.concat([df1,s2],axis = 1)
s3 = pd.Series(['c',10,11])
df1 = pd.concat([df1,s3],axis = 1)

If my example above is some how misleading perhaps using the example from the docs will help.

Quoting: Appending rows to a DataFrame.
While not especially efficient (since a new object must be created), you can append a single row to a DataFrame by passing a Series or dict to append, which returns a new DataFrame as above. End Quote.

The example from the docs appends "S", which is a row from a DataFrame, "S1" is a Series and attempting to append "S1" produces an error. My question is WHY will appending "S1 not work? The assumption behind the question is that a DataFrame must code or contain axes information for two axes, where a Series must contain only information for one axes.

df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
s = df.xs(3); #third row of DataFrame
s1 = pd.Series([np.random.randn(4)]); #new Series of equal len
df= df.append(s, ignore_index=True)

Result

   0  1

0  a  b

1  5  8

2  6  9

Desired

   0  1 2

0  a  5 6

1  b  8 9

Upvotes: 26

Views: 28252

Answers (3)

jcdude
jcdude

Reputation: 3011

The best way is to use DataFrame to construct a DF from a sequence of Series, rather than using concat:

import pandas as pd
s1 = pd.Series(['a',5,6])
s2 = pd.Series(['b',8,9])
pd.DataFrame([s1, s2])

Output:

In [4]: pd.DataFrame([s1, s2])
Out[4]: 
   0  1  2
0  a  5  6
1  b  8  9

Upvotes: 13

Dick Eshelman
Dick Eshelman

Reputation: 1143

A method of accomplishing the same objective as appending a Series to a DataFrame is to just convert the data to an array of lists and append the array(s) to the DataFrame.

data as an array of lists

def get_example(idx):

   list1 = (idx+1,idx+2 ,chr(idx + 97))
   data = [list1]
   return(data)

df1 = pd.DataFrame()

for idx in range(4):

   data = get_example(idx)
   df1= df1.append(data, ignore_index = True)

Upvotes: 0

TomAugspurger
TomAugspurger

Reputation: 28936

You were close, just transposed the result from concat

In [14]: s1
Out[14]: 
0    a
1    5
2    6
dtype: object

In [15]: s2
Out[15]: 
0    b
1    8
2    9
dtype: object

In [16]: pd.concat([s1, s2], axis=1).T
Out[16]: 
   0  1  2
0  a  5  6
1  b  8  9

[2 rows x 3 columns]

You also don't need to create the empty DataFrame.

Upvotes: 17

Related Questions